FarCry CMS Rules: Populating Library Data

This blog post aims to cover 2 methods of pre-filtering the pop-up library initially for your content team to easily navigate content object entries when applying rules when using FarCry CMS.

These methods are great for large sites that have a lot of content. Both do a great job at filtering down the bulk of entries a content person may have to navigate when selecting content entry items.

Both methods are built into FarCry and require a small amount of work but will really make your site that much better to use on the CMS side of things.

Assumptions

This post assumes you know how to properly deploy a rule for FarCry. We will be inside the 1 of the 2 files that are the basis for the rules. “yourRuleName.cfc” Which is the arbitrary name of my rule properties cfc file.

By Default

When joining in content objects to pick. FarCry deploys rules by pulling in every content object entry. Our aim is to only pull in content object entries via a query WHERE clause or that are tagged via categories, giving FarCry a more “WordPress”  tagging feel.

Initial Setup

First we set up our rule, lets call it “myRule”, (rules / myRule.cfc) that we want to be able to pick from the content object called “myContentObject”. So we deploy myRule.cfc with the following Farcry formtools properties.

<cfcomponent 
   displayname="My Rule" 
   extends="farcry.core.packages.rules.rules" 
   hint="Use this rule to pick content object entries">
 
 <cfproperty 
   name="ruleTitle" type="string" hint="title"
   ftseq="1" 
   ftFieldset="Rule Configuration" 
   ftLabel="Admin Title"
   fthint="Title used to identify the rule">
 
 <cfproperty 
   name="aObjects" 
   type="array"
   hint="The selected items to be displayed." 
   ftSeq="2" 
   ftFieldset="Rule Configuration" 
   ftLabel="Selected Items" 
   ftHint="Displaying My Rule Items"
   ftAllowAdd="false"
   ftAllowCreate="false"
   ftJoin="myContentObject">

</cfcomponent>

As you can see, it’s a pretty straight forward rule, the admin title is required for FarCry to manage itself, and “aObjects” is the picker property to pull in all the content objects via ftJoin called “myContentObject”, ftJoin does the work for us querying and pulling in all the entries for myContentObject.

The First Method

For the first method we are going to use FarCry’s library property attribute called ftlibrarydatasqlwhere

ftlibrarydatasqlwhere is a simple where clause filter for the library data result set. To use it, just add it on to your content picker property, so our “aObjects” becomes.

<cfproperty 
   name="aObjects" 
   type="array"
   hint="The selected items to be displayed." 
   ftSeq="2" 
   ftFieldset="Rule Configuration" 
   ftLabel="Selected Items" 
   ftHint="Displaying My Rule Items"
   ftAllowAdd="false"
   ftAllowCreate="false"
   ftJoin="myContentObject"
   ftlibrarydatasqlwhere="status='approved'">

This is super simple if you know ahead of time what you need to filter on. In this case, we simply want all the “myContentObject” entries that are approved. FarCry assumes the “WHERE” part in the clause, so we just need to pass in the property / operator / value structure. We can even extend upon this with “AND” in our WHERE clause. Like status=’approved’ AND color=’red’ or whatever.

The neat part about this simple library data population is that we can leverage ftlibrarydatasqlorderby as well. So we can order our results by column. Just pass it in as the value. ftlibrarydatasqlorderby="datetimelastupdated"

That’s all we need for this method to pull in all the entries for myContentObject that are “status approved” and ordered by “datetimelastupdated”. Upload, reload the application and enjoy the ease of use.

 

The Second More Advanced Method

The second method requires a bit more work, but the results can be amazing. To start we set up our rule in much the same manor, only instead of using FarCry’s
ftlibrarydatasqlwhere attribute. We will use a different attribute called ftLibraryData

So our cfproperty for “aObjects” will look like this.

<cfproperty 
   name="aObjects" 
   type="array"
   hint="The selected items to be displayed." 
   ftSeq="2" 
   ftFieldset="Rule Configuration" 
   ftLabel="Selected Items" 
   ftHint="Displaying My Rule Items"
   ftAllowAdd="false"
   ftAllowCreate="false"
   ftJoin="myContentObject"
   ftLibraryData="taggedWith_states">

 

ftLibraryData calls a public method on the content type to pre-populate the pop-up library based off what the method returns, it is always a query result.

“taggedWith_states” is a arbitrary name for a cffunction we will set up in the cfc file of the content object type we wish to populate the library via ftJoin. Since we are call “myContentObject” in ftJoin, we will add our function to types / myContentObject.cfc. We are now done with rules / myRule.cfc. Save, upload, and refresh the application.

In myContentObject.cfc

Navigate to “types” and open your content object file “myContentObject.cfc” and lets add in the cffunction called “taggedWith_states”.

For the purpose of this example I will only have 2 fields in this content object, a title, and categories, a field for associating FarCry categories with each entry. Our categories will be for US states, so we can tag each entry with one or more “states”.

<!--- @@Description: My Content Object Type --->
<!--- @@Developer: Me --->
<cfcomponent 
   name="myContentObject"
   extends="farcry.core.packages.types.versions" 
   output="false" 
   displayname="My Content Object" 
   icon="fa-external-link">

<cfproperty 
   ftSeq="1" 
   ftwizardStep="Start" 
   ftFieldset="General Details" 
   name="Title" 
   ftlabel="Title" 
   type="nstring" 
   hint="Title of object" 
   required="yes"
   default="" 
   ftValidation="required">

<cfproperty 
   ftSeq="2" 
   ftwizardStep="Start" 
   ftFieldset="Categories" 
   name="catHTML" 
   type="nstring" 
   fthint="Pick A State, Or More"
   required="no"
   default=""
   ftType="Category"
   ftAlias="root"
   ftLabel="Categories">

</cfcomponent>

The title is a straight text field entry, and the categories property will render a checkbox tree with all the categories we entered into FarCry. Lets assume we have a “states” category with all the US states as items.

Now here is where we will add in our function called “taggedWith_state”. So our myContentObject.cfc file becomes.

<!--- @@Description: My Content Object Type --->
<!--- @@Developer: Me --->
<cfcomponent 
   name="myContentObject"
   extends="farcry.core.packages.types.versions" 
   output="false" 
   displayname="My Content Object" 
   icon="fa-external-link">

<cfproperty 
   ftSeq="1" 
   ftwizardStep="Start" 
   ftFieldset="General Details" 
   name="Title" 
   ftlabel="Title" 
   type="nstring" 
   hint="Title of object" 
   required="yes"
   default="" 
   ftValidation="required">

<cfproperty 
   ftSeq="2" 
   ftwizardStep="Start" 
   ftFieldset="Categories" 
   name="catHTML" 
   type="nstring" 
   fthint="Pick A State, Or More"
   required="no"
   default=""
   ftType="Category"
   ftAlias="root"
   ftLabel="Categories">

<cffunction 
   name="tagedWith_states" 
   access="public" 
   output="false"
   returntype="query" 
   hint="Return a qry for all entries tagged with the catHTML (state) 
   of the page which this will live on">

   <cfargument 
      name="primaryID" 
      type="uuid" 
      required="true"
      hint="ObjectID of the rule, or object that we are attaching to" />
 
 <!--- get the catHTML of the state that is the current page 
       1. Work our way back up from primaryID, (objid of the rule)
       2. to the objid of the container
       3. to the objid of the page the container is on
       4. to the catHTML (state) of the page
 --->
       <cfquery datasource="#application.dsn#" name="getCatHTML">
          SELECT StateData.catHTML FROM container_aRules
            JOIN refContainers 
              ON container_aRules.parentid = refContainers.containerid
            JOIN StateData 
              ON refContainers.objectid = StateData.objectid
           WHERE container_aRules.data = '#primaryID#'
       </cfquery>
 
<!--- Then select all of the entries for this cont obj 
      tagged with the catHTML (state) of the page --->
      <cfquery datasource="#application.dsn#" name="q">
          SELECT *
          FROM myContentObject
          WHERE catHTML LIKE '%#getCatHTML.catHTML#%'
       </cfquery>
 
    <cfreturn q />
</cffunction>

</cfcomponent>

Not too scary right? All you need to do is set up a function with the name of the name you are calling from the rule cfc “taggedWith_states” and return a query. Then in the function you can do any kind of query you want. The only argument is “primaryID” which is automatically passed into the function for you via Farcry as it always tells you the objectID of the calling parent. In this case a rule. So we know the objectID of the rule on the page.

The cool thing is now, we can work our way in any direction via queries of the FarCry tables. I’m giving you a neat example here as I’m working my way back up the tree on the site page from, Rule to Container to Page. So in this example, we know everything about the parent page that the container that has the rule lives on via JOINS in our query. Just follow the trail of objectIDs.

This is what I like best about FarCry, I can query my way around the site and know everything about everything. So in this example. I have a detail page for a content object called “StateData”, let’s say “Maryland” that is tagged with a state category “Maryland”, that has a container on it, with my “myRule” attached to it. And that rule can now look at the catHTML of the parent page and populate the “myRule” with only content tagged to “Maryland” since that is all I would want to pick from to put on my Maryland page.

Like I said, you can use any query here and return back that query to the rule to populate your data for choosing with ease.

The cool part is, you can use this method with multiple ftJoins, just drop your single function into each content object type you wish to leverage library filtering.

Happy Coding!

 

 

 

 

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s