## Subject Keywords (Categories)

Content Repository : Developer Guide

### Overview

Subject Keywords are used to implement categorization for the Content Management system. A Subject Keyword is a small label, such as "Oracle Documentation" or "My Favorite Foods", which can be associated with any number of content items. Thus, content items may be grouped by arbitrary categories. For example, assigning the Subject Keyword "My Favorite Foods" to the content items "Potstickers", "Strawberries" and "Ice Cream" would indicate that all the three items belong in the same category - namely, the category of the user's favorite foods. The actual physical location of these items within the repository is irrelevant.

Subject Keywords may be nested to provide more detailed control over categorization; for example, "My Favorite Foods" may be further subdivided into "Healthy" and "Unhealthy". Subject Keywords which have descendants are referred to as "Subject Categories".

### Data Model

The `content_keyword` object type is used to represent Subject Keywords (see `content_keyword.sql`) The `content_keyword` type inherits from `acs_object`:

     acs_object_type.create_type ( supertype => 'acs_object', object_type
       => 'content_keyword', pretty_name => 'Content Keyword',
       pretty_plural => 'Content Keywords', table_name => 'cr_keywords',
       id_column => 'keyword_id', name_method => 'acs_object.default_name'
       );

In addition, the `cr_keywords` table (see `content-create.sql`) contains extended attributes of Subject Keywords:

    create table cr_keywords (
      keyword_id             integer
                             constraint cr_keywords_pk
                             primary key,
      heading                varchar2(600)
                             constraint cr_keywords_name_nil
                             not null,
      description            varchar2(4000)
    );

In `content-keyword.sql`:

    attr_id := acs_attribute.create_attribute (
      object_type    => 'acs_object',
      attribute_name => 'heading',
      datatype       => 'string',
      pretty_name    => 'Heading',
      pretty_plural  => 'Headings'
    );

    attr_id := acs_attribute.create_attribute (
      object_type    => 'content_keyword',
      attribute_name => 'description',
      datatype       => 'string',
      pretty_name    => 'Description',
      pretty_plural  => 'Descriptions'
    );

Thus, each Subject Keyword has a `heading`, which is a user-readable heading for the keyword, and a `description`, which is a somewhat longer description of the keyword.

The `cr_item_keyword_map` table (see `content-create.sql`) is used to relate content items to keywords:

    create table cr_item_keyword_map (
      item_id          integer
                       constraint cr_item_keyword_map_item_fk
                       references cr_items
                       constraint cr_item_keyword_map_item_nil
                       not null,
      keyword_id       integer
                       constraint cr_item_keyword_map_kw_fk
                       references cr_keywords
                       constraint cr_item_keyword_map_kw_nil
                       not null
      constraint cr_item_keyword_map_pk
      primary key (item_id, keyword_id)
    );

### API Access

The API used to access and modify content keywords are outlined below. The function names are links that will take you to a more detailed description of the function and its parameters.

Function/Procedure | Purpose | Description
--- | --- | ---
new | Create a new Subject Keyword | This is a standard `new` function, used to create a new Subject Keyword. If the parent id is specified, the new keword becomes a child of the parent keyword (which may now be called a Subject Category)
delete | Delete a Subject Keyword | This is a standard `delete` function, used to delete a Subject Keyword
get_heading set_heading get_description set_description | Manipulate properties of the Keyword | You must use these functions to manipulate the properties of a keyword. In the future, the data model will be updated to handle internatiolization, but the API will not change.
item_assign item_unassign is_assigned | Assign Keywords to Items | These functions should be used to assign Subject Keywords to content items, to unassign keywords from items, and to determine whether a particular keyword is assigned to an item. The `is_assigned` function can be used to determine if a keyword matches a content item, based on the `recurse` parameter: If `recurse` is set to `'none'`, `is_assigned` will return `'t'` if and only if there is an exact assignment of the keyword to the item. If `recurse` is set to `'down'`, `is_assigned` will return `'t'` if there is an exact assignment of the keyword to the item, or if a narrower keyword is assigned to the item. For example, a query whether "Potstickers" is assigned the category "My Favorite Foods" will return `'t'` even if "Potstickers" is only assigned the category "Healthy". If `recurse` is set to `'up'`, `is_assigned` will return `'t'` if there is an exact assignment of the keyword to the item, or if a broader Subject Category is assigned to the item. For example, a query whether "Potstickers" is assigned the category "Healthy" will return `'t'` even if "Potstickers" is assigned the broader category "My Favorite Foods".