0



03Jul2011

Getting the Parent Page of an Asset

Problem: you need to know where an asset has been placed in the SitePlan.

Well, I have a similar situation. I designed a site in a such way that the css of an asset is picked looking at  the category of the parent page.

This is not odd: when you navigate a site and reach a page with a given style (that changes according to the sections of the site), if  you  navigate to the detail , usually what  you want is children keep the same style of the parent page.

So, basically I want to locate the parent page (or at least the first parent page, since I know the asset can be actually placed in more than one page).

However, that is the problem. What is the solution?

Note: I normally use the infamous parameter p to find the parent page. Well, I found the p is not the more appropriate way of implementing the concept "pick the style from the parent". There are way too many cases where assigning the p correctly is difficult.

So, how do you think you can find the parent? The simple solution is:  enumerating all the pages, then check all the children until you find your asset. Well, I am sure you will agree if I say this solution is horrible, both performance wise and coding wise.

Fortunately I found is a better solution that I am posting here. This post is also a  good opportunity to introduce an advanced Content Server techniques as well: the TreeManager.

The solution is basically looking into the table AssetRelationTree (that stores  all the  parent-children relationship) using the TreeManager (an internal server of ContentServerm  accessible with a tag  available in the tag libriry).

How to find the parent pages of a given asset

The problem,  expressed in a more technical way, is: given an asset identified by his content id (stored in the "cid" variable),  find the id of all the pages having that asset as a children. My Solution follows.

Step 1: locate a list of all the children assets in the AssetRelationTree with the TreeManager

<ics:treemanager>
  <ics:argument name="ftcmd" value="findnode"/>
  <ics:argument name="treename" value="AssetRelationTree"/>
  <ics:argument name="where" value="oid"/>
  <ics:argument name="oid" value='<%=ics.GetVar("cid")%>'/>
</ics:treemanager>

Step 2: extract parents using their node id (nid) and getparent

The returned list is only a list of the available relations.
Using the nid of such a relation you can look for the parent.

This is the code to retrieve the parents:

<ics:copylist from="AssetRelationTree"  to="List"/>
<ics:listloop listname="List">
  <ics:listget listname="List" fieldname="nid"  output="nid" />
  <ics:treemanager>
    <ics:argument name="ftcmd" value="getparent"/>
    <ics:argument name="treename" value="AssetRelationTree"/>
    <ics:argument name="node" value='<%=ics.GetVar("nid")%>'/>
  </ics:treemanager>
  <!-- now do something with the found id - see Step3 -->
</ics:listlooop>

Note that I copied the list from  the first TreeManager call because another call to TreeManager will  store the result always in the same  AssetRelationTree list. Since I have to call the TreeManager again I am preventing the list to be overwritten and I am working on a copy.

Step 3: grab parents and do something with them.

Inside the loop in Step2, you will get all the parents of the asset.

You can retrive the id of a parent with

<ics:listget listname="AssetRelationTree" fieldname="oid" output="p"/>

also you can read the type with

<ics:listget listname="AssetRelationTree" fieldname="otype" output="ptype"/>

but it should be always "Page". Now you can do what you want with the parent (in my case, I was just using the retrieved parent to set the p parameter).

Bonus: how to do it all with a simple query

Well, you could retrieve the parent with this simple database query, tested with jumpstart and hypersonic:

select  otype,oid from AssetRelationTree where nid in
(select nparentid from AssetRelationTree where oid = 123456789)

where 123456789 is the cid of the asset you are looking for its parents.

However, as a general rule, I do not trust too much explicit queries because they are database dependent.

 



Posted by msciab
03Jul2011