5Categories

Categories contain content, configuration or references that are used in several pages or content elements. Categories are organised as a tree where at each level information can be inherited or overridden. A document can have a category input element creating a reference to the category document chosen from the category tree.

Use cases

A configuration task is a document of a special type that defined by its type is assigned to a category document. This configuration task declares a special configuration type for instance a navi reference, an AD configuration, a header/footer layout/content/config, ... So maybe in the production of a page header the category is requested for the header logo task and the internal logic will find a configuration at this category level or at any category level above.

While several pages or content entities reference categories the search is able to filter content by category for instance when the task is "Find all articles from category X".

Document structure and Additional CMS properties

The documents of the category tree are placed at a special folder in the CMS. A category document type has to be created containing a string field for a view name and at least a linklist property containing configuration tasks. The category document must be named as configured in the additional properties. Only one document of the category document type correctly named is placed in a folder. To create a sub category create a subfolder with a category document. The category and subcategory are not linked. The connection is identified only as a category document in the subfolder.

The following additional properties have to be set:

category.folderpath

Root of the category tree

category.documentname

The name of the category document

category.documenttypeid

The ID of the document type of the category document

category.propertyname.viewname

The name of the property containing the view name for the category

In the cmsWorks administration tools these properties can simply be set under the Entry Additional CMS properties.

In programming there is a direct access to these configuration properties:

app.cmsworks.service.cms.util.CategoryConfig.getCategoryFolderPath(cms);
app.cmsworks.service.cms.util.CategoryConfig.getCategoryDocumentName(cms);
app.cmsworks.service.cms.util.CategoryConfig.getCategoryDocumentTypeId(cms);
app.cmsworks.service.cms.util.CategoryConfig.getCategoryPropertyNameViewname(cms);

If there document types for several different pages or any other document types containing a category reference, the category field name should be always the same. In that case a simple CategoryAccess object can be used to access the category of a document to find and use a configured task.

The DocumentModelConstants declare Methods to be implemented to configure the project to the existing document model. This can be added into the documentmodel.jsf

// declare the resource type id of the resource type "category"
public int getRT_CATEGORY() { return RT_CATEGORY; }
// declare the field name in a document referencing the category
public String getPT_CATEGORY() { return "category"; }
// declare the name of the filed in the category document containing the view name of this category
public String getPT_CATEGORY_VIEWNAME() { return PT_CATEGORY_VIEWNAME; }

// declare the name of the field containing the config tasks in the category document
public String getPT_CATEGORY_CONFIGS() { return "tasks"; }
// declare the document type id of the document type for config tasks
public int getRT_CONFIGTASK() { return RT_CONFIGTASK; }
// declare the field name of the task type in the config task document type
public String getPT_CONFIGTASK_TYPE() { return "type" };

To get the category model from a document having a category field simply use

app.cmsworks.cms.document.CategoryModel dmCategory = new app.cmsworks.cms.document.CategoryModelAccess(dmAny).getCategory();

This returns either a referenced category or null if the category is not set or a CMSPropertyAccessException if the document has no category property.

With

app.cmsworks.cms.document.CategoryModel dmCategory = new app.cmsworks.cms.document.CategoryModelAccess(dmAny).getCategory(errors);

an Error appears in the generated preview giving the hint that the category in the document was not set.

Accessing a category configuration task

Preparing the access of a configuration task the editors desktop configuration declares the types of the configuration task:

"document": { // in the document section of q-custom.js
"configtask": { // for the document of type Configtask
"type_prop": { // the field type
xtype: "itwselectbox", // show a dropdown
options: [
[ 0,"--- no type ---" ],
[ 1,"Header logo" ],
[ 2,"Navi root" ],
[ 3,"Footer" ]
]
}
}
}

According to this list it's recommended to create a Constant collection representing this task type list (much alike the document types and document field contents in configtask.jsf)

/** Defines a list of constants to name the types of config tasks
*/
public static class ConfigTask {
final static int NO_TYPE = 0;
final static int HEADER_LOGO = 1;
final static int NAVI_ROOT = 2;
final static int FOOTER = 3;
...

public static String getName(int id) {
switch (id) {
case NO_TYPE : return "no type";
case HEADER_LOGO : return "Header logo";
case NAVI_ROOT : return "Navi root";
case FOOTER : return "Footer";
...
}
return "unknown";
}
}

And finally for the actual access:

// accessing the category from a document dmAny
app.cmsworks.cms.document.CategoryModel dmCategory = new app.cmsworks.cms.document.CategoryModelAccess(dmAny).getCategory();
// accessing the task of the type HEADER_LOGO
app.cmsworks.cms.document.DocumentModel dmTask = dmCategory.getTask(ConfigTask.HEADER_LOGO);
// accessing the image document in the content list of the task document (looking for the first document of type Medium)
app.cmsworks.cms.document.DocumentModel dmLogo = dmTask.getLinkedResource(Types.PT_CONFIG_TASK_CONTENT, Types.RT_MEDIUM, 0);

If the configuration task was not found in this category and also not in any of its parent categories, a Nullpointer is returnd. A more transparent way to access the task is to add an ErrorView and a description message:

// adding the errorview and an error message if the task cannot be found
app.cmsworks.cms.document.DocumentModel dmTask = dmCategory.getTask(ConfigTask.HEADER_LOGO, errors, "Error accessing category configuration task of type " + ConfigTask.getName(ConfigTask.HEADER_LOGO));

Category features

The category model also provides methods to access several category related data:

String getViewName()

returns the content of the view name field from the category document

String getBaseName()

returns the name of the folder containing this category document

int getLevel()

returns the level of the category

CategoryModel getParentCategory()

retuns the parent category model

String getCategoryNameForLevel(int level)

returns the viewname for a category of a special level regarding only this category and parent categories

String getCategoryNamesForLevels(int levelStart, int levelEnd, String glue)

returns the joined category names

DocumentModel getTask(int taskId)

returns a task of a type in this category document and if not found searching in the parent category document