Custom Overview Tab - Related Content

FarCry makes it easy to add tabs to an object's overview. This example shows how to use this to add a tab that shows all content in the system that is related to the selected object

The short explanation of this code is that:

  1. I created a webskin called webtopOverviewTabRelated.cfm and put it in /webskin/types,
  2. looped over application.stCOAPI[stObj.typename].aJoins to get all the relationships that the type is a part of,
  3. used application.fapi.getContentObjects() to retrieve content with one of those relationships with this object (with some deduping in the process),
  4. then outputed that content using the librarySelect webskin (the webskin used in library pickers)

These custom tabs are only loaded when a user clicks on them, via AJAX, which means that all of this is only executed and rendered if the user is actually interested.

webtopOverviewTabRelated.cfm
<cfsetting enablecfoutputonly="true" />
<!--- @@displayname: Related Content --->

<cfimport taglib="/farcry/core/tags/webskin" prefix="skin" />

<cfset stLocal.aRelated = application.stCOAPI[stObj.typename].aJoins />
<cfset stLocal.qRelated = querynew("objectid,typename,notes") />

<cfloop from="1" to="#arraylen(stLocal.aRelated)#" index="stLocal.i">
	<cfset stLocal.st = stLocal.aRelated[stLocal.i] />
	<cfset stLocal.args = structnew() />
	<cfif stLocal.st.direction eq "from">
		<cfif structkeyexists(application.stCOAPI[stLocal.st.coapiType],"displayname")>
			<cfset stLocal.note = "#application.stCOAPI[stLocal.st.coapiType].displayname# #application.stCOAPI[stLocal.st.coapiType].stProps[stLocal.st.property].metadata.ftLabel#" />
		<cfelse>
			<cfset stLocal.note = "#stLocal.st.coapiType# #application.stCOAPI[stLocal.st.coapiType].stProps[stLocal.st.property].metadata.ftLabel#" />
		</cfif>
		
		<cfset stLocal.args.typename = stLocal.st.coapiType />
		<cfset stLocal.args["#stLocal.st.property#_in"] = stObj.objectid />
		<cfset stLocal.q = application.fapi.getContentObjects(argumentCollection=stLocal.args) />
		
		<cfloop query="stLocal.q">
			<cfset stLocal.matched = false />
			<cfloop query="stLocal.qRelated">
				<cfif stLocal.qRelated.objectid[stLocal.qRelated.currentrow] eq stLocal.q.objectid[stLocal.q.currentrow]>
					<cfset querysetcell(stLocal.qRelated,"notes",stLocal.qRelated.notes[stLocal.qRelated.currentrow] & ", #stLocal.note#",stLocal.qRelated.currentrow) />
					<cfset stLocal.matched = true />
				</cfif>
			</cfloop>
			<cfif not stLocal.matched>
				<cfset queryaddrow(stLocal.qRelated) />
				<cfset querysetcell(stLocal.qRelated,"objectid",stLocal.q.objectid[stLocal.q.currentrow]) />
				<cfset querysetcell(stLocal.qRelated,"typename",stLocal.q.typename[stLocal.q.currentrow]) />
				<cfset querysetcell(stLocal.qRelated,"notes",stLocal.note) />
			</cfif>
		</cfloop>
	<cfelse><!--- to --->
		<cfif isarray(stObj[stLocal.st.property])>
			<cfset stObj[stLocal.st.property] = arraytolist(stObj[stLocal.st.property]) />
		</cfif>
		<cfif structkeyexists(application.stCOAPI[stLocal.st.coapiType],"displayname")>
			<cfset stLocal.note = "#application.stCOAPI[stLocal.st.coapiTypeOther].displayname# #application.stCOAPI[stLocal.st.coapiTypeOther].stProps[stLocal.st.property].metadata.ftLabel#" />
		<cfelse>
			<cfset stLocal.note = "#stLocal.st.coapiTypeOther# #application.stCOAPI[stLocal.st.coapiTypeOther].stProps[stLocal.st.property].metadata.ftLabel#" />
		</cfif>
		<cfif len(stObj[stLocal.st.property])>
			<cfset stLocal.q = application.fapi.getContentObjects(typename=stLocal.st.coapiType,objectid_in=stObj[stLocal.st.property]) />
			
			<cfloop query="stLocal.q">
				<cfset stLocal.matched = false />
				<cfloop query="stLocal.qRelated">
					<cfif stLocal.qRelated.objectid[stLocal.qRelated.currentrow] eq stLocal.q.objectid[stLocal.q.currentrow]>
						<cfset querysetcell(stLocal.qRelated,"notes",stLocal.qRelated.notes[stLocal.qRelated.currentrow] & ", #stLocal.note#",stLocal.qRelated.currentrow) />
						<cfset stLocal.matched = true />
					</cfif>
				</cfloop>
				<cfif not stLocal.matched>
					<cfset queryaddrow(stLocal.qRelated) />
					<cfset querysetcell(stLocal.qRelated,"objectid",stLocal.q.objectid[stLocal.q.currentrow]) />
					<cfset querysetcell(stLocal.qRelated,"typename",stLocal.q.typename[stLocal.q.currentrow]) />
					<cfset querysetcell(stLocal.qRelated,"notes",stLocal.note) />
				</cfif>
			</cfloop>
		</cfif>
	</cfif>
</cfloop>

<cfoutput><table width="100%"><tr style="font-weight:bold;"><th>Related Object</th><th>Related Through</th></tr></cfoutput>
<cfloop query="stLocal.qRelated">
	<cfoutput><tr><td></cfoutput>
	<skin:view objectid="#stLocal.qRelated.objectid#" typename="#stLocal.qRelated.typename#" webskin="librarySelected" />
	<cfoutput></td><td>#stLocal.qRelated.notes#</td></tr></cfoutput>
</cfloop>
<cfoutput></table></cfoutput>

<cfsetting enablecfoutputonly="false" />