Best Practices and Cookbooks

From ActionApps Documentation
Jump to: navigation, search

How to create a hierarchical navigation using related items

We will need one slice for the categories. Then we need to make it display the hierarchy in the Item Manager. The design will also be used when we relate it to the slice with the actual content for selecting which category (categories) a particular item falls under. Then we will look at creating a template for displaying the navigational menu on the site, including the selected category highlighting. Last thing we'll look at is how to only display items falling under a certain category, and how to display items falling under a category or it's subcategories.

Prepare a new slice for your categories

First we have to decide which fields do we need for the categories. Having categories stored in the slice gives us an possibility to include an unlimited amount of additional information about each category - a picture, introductory text and so on. Here we will need just 3 fields:

  • Category Headline containing the label of each category
  • Category Description containing a textual information describing the category
  • Subcategories of this category containing references to all subcategories of this category

Note 1: We could have also used parent category relation (an opposite direction), but we want to be able to define the ordering of the subcategories in the related items input control

Note 2: This also assumes that we don't use so called cross linking between categories across the tree hieararchy. Each category must have exactly one parent category

The slice structure should look something like this:

Hcrel fields.gif

The input controls for headline and description are standard (text field and text area), the Subcategories of this category must be a related item window with following buttons (Genes and Health is shown here):

Hcrel fields2.gif

Note: Parameters 10:A:1::MNRED::::. The New button allows user to create a new subcategory quite easily, without having to go throught the item manager. The Up nad Down buttons control the order of the subcategories.

Now you can fill the slice with your date, i.e. category tree. We make one special item with the headline ROOT. All the top level categories should have the ROOT as a parent. This is important, because it allows us to control the order of the top level categories, and also to identify that we have descended to the bottom of the tree by comparing the name (this will become clearer later). In this example we used following structure:


ROOT
|- Human Genetics 
|      |- Genes and Health 
|      |        |- Press Releases
|      |        |- Reports
|      |        |- Briefings
|      |        |- Consultation responses
|      |- Links
|      |- Reproductive Genetics
|      |- Genetic research
|      |- Genes and Discrimination
|      |- Genes and Marketing
|      |- Genes and Health
|- Archive 	
|- Publications
|- Bio Weapons 	
|- Research Agendas and Patenting 	

Displaying hierarchy in the item manager

After you have followed the steps described above, you should now see in the Item manager a flat list of categories. That is not very convenient, as the user needs to see where the category lies in th hierarchical tree. An obvious solution would be to display the tree as it will be displayed in the main navigation. It is probabaly possible, but quite complicted. In this quide we will build a compromise simple solution, hopefully usable. The proposd solution is to have the item manager displaying the hierarchy like this:


Human Genetics ->Genes and Health ->Consultation responses
Human Genetics ->Genes and Health ->Briefings
Human Genetics ->Genes and Health ->Reports
Human Genetics ->Genes and Health ->Press Releases
Human Genetics ->Links
Human Genetics ->Reproductive Genetics
Human Genetics ->Genetic research
Human Genetics ->Genes and Discrimination
Human Genetics ->Genes and Marketing
Human Genetics ->Genes and Health
Archive
Publications
Bio Weapons
Research Agendas and Patenting
Lab Use
GM Animals
ROOT 

Note: The ordering of items here is slightly inconvenient (default is publish date) but we leave it aside for the moment.

So what we want to do is for each category display the name of the category preceeded by all it's parents.

The building stones for this will be one alias, one conditional function (f_c), and two views included via {view} syntax. The underlying mechanism will be Recursion.

Each string above follows a simple formula:

List of Parents -> headline

If we could construct such an alias _#PARENTS_ which lists all the parents of an item in question, separated by "->", then we are done, because then the string is simply printed by putting:

_#PARENTS_ _#HEADLINE 

in the item manager template.

Let's see what the parent _#PARENTS_ is. It's either:

  • an empty string if the parent category is called ROOT or
  • the name of the parent category followed by "->" and preceeded by the list of the parent's parents :-)

Note: Math geeks already see that the above is the definition of recursive function F(0) = "" and F(n + 1) = f(F(n))

In ActionApps language, this means that the alias _#PARENTS_ there will be done through a conditional function which does this:

  • lookup the name of the parent category
  • if that name is ROOT or the category doesn't have a parent, produce an empty string
  • if parent exists and it's not ROOT, return the name a name of this category, preceeded by "->", preceeded by the list of it's parents

We could just use one view, but because we keep optimization in mind, we'll create two views, one for actual lookup of the category name, and another fast one that simply returns "ROOT" if we should print empty string and something else if not:

Lookup view

Demo.jpg View No. 129, Name: Resolve Parent Category Name, Slice: Navigation Tree Demo - Categories

The lookup view will be a view of Item Listing type, restricted to print only 1 item (Fulltext would do as well), printing following string for each (odd) row:

_#PARENTS_ {headline........}

which says: "Print all my parents, and then my headline".

Note: The headline is then followed by an invisible item id in the live demo, which we will make use of later.

We use Condition 1 to make sure that we are sarching for the true parent of a category in question, so

Condition 1:  Subcategories of this category = <value> 

where the <value> will be a child ID sent to the view by the _#PARENTS_ alias (see below)

Note: If <value> is nonexistent or the parent doesn't exist we return string "ROOT" through the "No item found"

Test view

Demo.jpg View No. 130, Name: Test for a parent category, Slice: Navigation Tree Demo - Categories

This is a trivial view which serves only one purpose. We have a category ID, and we want to know whether it's already on the top level (that means that the parent is "ROOT" or doesn't exist), or not. If so, we return value "ROOT", if not, we return something else.

The quickest view is supposingly URL listing. We are also going to hard code the special "ROOT" item ID into the condition. So:

   Condition 1: Subcategories of this category = <child ID>
   Condition 2: Long ID <> put the long ID of ROOT item here
Listing length: 1
 No item found: ROOT

Conditional function

Demo.jpg Alias: _#PARENTS_, Slice: Navigation Tree Demo - Categories

Now we can create the conditional function described above. Let's review what we need to do:

  • If the test for parent results in the value ROOT, do nothing and return
  • Otherwise, print the name of the parent (and all parent's parents)

Note: In case 1, we have reached the top of the structure, which is the bottom of the recursion.

The alias definition for _#PARENTS_ will use f_c, with following parameters:

     condition: !ROOT
         begin: {view.php3?vid=129&cmd[129]=c-1-{id..............}}-<
           end: 
          else: 
    cond_field: {view.php3?vid=130&cmd[130]=c-1-{id..............}}	
skip_the_field: 1

Test it

Put:

_#PARENTS_ _#HEADLINE 

in the item manager template.