The ACS content repository package includes two pre-defined content types, the basic item -- or content_revision type -- and the image type. Other predefined content types include the acs_message_revision, which is used by the ACS messaging package. All other content types should have content_revision as an ancestor type.
You may also define content types to suit your own needs by using the create_type procedure in the content_type package:
procedure create_type ( --/** Create a new content type. Automatically create the attribute table -- for the type if the table does not already exist. -- @author Karl Goldstein -- @param content_type The name of the new type -- @param supertype The supertype, defaults to content_revision -- @param pretty_name Pretty name for the type, singular -- @param pretty_plural Pretty name for the type, plural -- @param table_name The name for the attribute table, defaults to -- the name of the supertype -- @param id_column The primary key for the table, defaults to 'XXX' -- @param name_method As in acs_object_type.create_type -- @see {acs_object_type.create_type} --*/ content_type in acs_object_types.object_type%TYPE, supertype in acs_object_types.object_type%TYPE default 'content_revision', pretty_name in acs_object_types.pretty_name%TYPE, pretty_plural in acs_object_types.pretty_plural%TYPE, table_name in acs_object_types.table_name%TYPE, id_column in acs_object_types.id_column%TYPE default 'XXX', name_method in acs_object_types.name_method%TYPE default null );
content_type denotes the name of the new content type you wish to define.
supertype defaults to content_revision, the root object type for content types.
Content types can also be defined by sub-classing other content types -- i.e. sub-types of the content_revision object type. Sub-classing another content type gives the designer the added benefit of any pre-existing attributes associated with the sub-typed content type. [include a compelling example of why that might be a good idea]
Here's an example of a content type definition; we made cr_demo_article_image a sub-class of the image content type so that it would inherit the properties of a basic image, but also included the caption field for text information to be included with the image:
declare attr_id integer; begin content_type.create_type ( content_type => 'cr_demo_article_image', supertype => 'image', pretty_name => 'Captioned image', pretty_plural => 'Captioned images', table_name => 'cr_demo_article_images', id_column => 'article_image_id' ); attr_id := content_type.create_attribute ( content_type => 'cr_demo_article_image', attribute_name => 'caption', datatype => 'text', pretty_name => 'Caption', pretty_plural => 'Captions' ); cm_form_widget.register_attribute_widget( content_type => 'cr_demo_article_image', attribute_name => 'caption', widget => 'text', is_required => 't' ); end; / show errors
The other procedural calls, content_type.create_attribute and cm_form_widget.register_attribute_widget are used for creating content type-specific attributes and for registering those attributes with the CMS form-builder.
Content types are largely distinguished by the attributes and methods associated with the type. CMS features convenient form-generating functions that build forms that request for values appropriate for each content type's attributes; in order to do this, CMS requires that content type attributes be registered in the database.
Register content type attributes with the create_attribute function in the content_type package:
function create_attribute ( --/** Create a new attribute for the specified type. Automatically creates -- the column for the attribute if the column does not already exist. -- @author Karl Goldstein -- @param content_type The name of the type to alter -- @param attribute_name The name of the attribute to create -- @param pretty_name Pretty name for the new attribute, singular -- @param pretty_plural Pretty name for the new attribute, plural -- @param default_value The default value for the attribute, defaults to null -- @return The id of the newly created attribute --*/ content_type in acs_attributes.object_type%TYPE, attribute_name in acs_attributes.attribute_name%TYPE, datatype in acs_attributes.datatype%TYPE, pretty_name in acs_attributes.pretty_name%TYPE, pretty_plural in acs_attributes.pretty_plural%TYPE default null, sort_order in acs_attributes.sort_order%TYPE default null, default_value in acs_attributes.default_value%TYPE default null, column_spec in varchar2 default 'varchar2(4000)' ) return acs_attributes.attribute_id%TYPE;
content_type contains the name of the content type with which the attribute is associated.
datatype should contain the one of the keyword datatype values contained in the acs_datatypes table, e.g. boolean, date, integer, money. If you wish to designate a datatype not already recorded in the acs_datatypes table, be sure to first insert your datatype into the table before registering your attribute.
content_type.create_attribute returns the attribute_id associated with your newly created attribute. See Defining Content Types [put ref links here to ch 2.2.1 when you learn how to do that] for an example of content_type.attribute_create in use.
A listing of file types, or mime types, whose storage is supported by the ACS content repository is stored in the cr_mime_types table. The ACS Content Repository supports four pre-registered mime types: plain and html text, as well as image GIFs and jpegs. The CMS News Demo also registers upon installation a few mime types designating audio files and video files:
begin /* Insert audio and video MIME types */ dbms_output.put_line('Inserting audio and video MIME types...'); insert into cr_mime_types ( label, mime_type, file_extension ) values ( 'Wave Audio File','audio/x-wav','wav' ); insert into cr_mime_types ( label, mime_type, file_extension ) values ( 'Basic Audio File','audio/basic','au' ); insert into cr_mime_types ( label, mime_type, file_extension ) values ( 'QuickTime Video','video/quicktime','qt' ); insert into cr_mime_types ( label, mime_type, file_extension ) values ( 'Mpeg Video','video/mpeg','mpg' ); end; / show errors
Each content object stored in CMS -- such as an image, text article or movie clip -- must be associated with a specific mime type. Also, each content type must also be pre-registered with all of the possible mime types with which that content type might be associated. For example, the image content type is registered to hold jpeg and gif files, but each instance of the image type -- that is, each image revision stored in the CMS -- will contain only one file of either the jpeg or gif file type.
Use content_type.register_mime_type to register pre-defined mime types with your newly created content type:
procedure register_mime_type ( content_type in cr_content_mime_type_map.content_type%TYPE, mime_type in cr_content_mime_type_map.mime_type%TYPE );
If the mime type you wish to register is not yet defined in the ACS content repository, define it by inserting a row in the cr_mime_types table as you saw done in CMS Default Mime Types.
Each piece of content requires atleast one template on which to be displayed before the content piece can be published by CMS. Templates serve as the framework upon which a content item is mounted. Templates are associated to content types, and each individual content item published by CMS will be displayed upon one of the templates associated to its content type. Multiple templates can be associated to multiple content types, allowing a single piece of content to be framed upon multiple templates, such as an image published with borders of various colors, or a single template to display multiple content types, such as using a common background for all text, images and video feeds.
Register templates through the CMS clipboard system, first by marking or adding items to the CMS clipboard, then by clicking on by going to the "Templates" tabbed page of the appropriate content type.
Templates can be marked for addition to the clipboard by opening the folder in which the template is contained. A listing of templates and folders will appear in the main right-side widow, a listing which includes a column of checkboxes for adding selected templates to the clipboard.
The above screenshot displays the contents of my /articles folder, which contains three templates already added to the clipboard.
Find the "Templates" page of your content type by first expanding the Content Types folder (and perhaps other sub-folders) on the CMS navigation tree, clicking on the folder or label for your content type, and then clicking on the light blue "Templates" tab in the main frame. With your mouse, point and click on Register marked templates to this content type, and then choose select from the clipboard the templates you wish to register.
The Template section of the Basic Item content type.
Though CMS does not come with any prepackaged templates, the CMS News Demo package does contain a variety of news article templates that include image and multimedia link tags. These templates can be found under /cms-news-demo/templates/demo_articles in the News Demo package.
The CMS cm_form_widget package can be used to generate metadata forms for creating items or adding revisions to existing items.
In order for CMS to be able to generate the metadata forms, it is necessary for each attribute of a content type to be registered to a form widget via the register_attribute_widget procedure.
cm_form_widget.register_attribute_widget( content_type => 'book_report', attribute_name => 'summary', widget => 'textarea', is_required => 'f' );
content_type used to identify the appropriate form widget.
attribute_name is the name of the attribute, used to identify the appropriate form widget.
widget is the form widget used to input a value for a content type attribute. See documentation for ATS form widgets for more info.
is_required is a flag indicating whether or not a value is required for the attribute form widget. By default, attribute form widgetes are not required.
Using register_attribute_widget will use the default values for the form widget. Usually these default values will be sufficient, but sometimes it may be necessary to customize the form widget with the set_attribute_param_value procedure.
cm_form_widget.set_attribute_param_value( content_type => 'book_report', attribute_name => 'summary', param => 'rows', param_type => 'onevalue', param_source => 'literal', value => 10 );
content_type used to identify the appropriate form widget.
attribute_name is the name of the attribute, used to identify the appropriate form widget.
param is one of the following:
an HTML tag corresponding to a specific form widget (rows for textarea, size for select widgets, maxlength for text boxes, ...)
an ATS form element tag (refer to the documentation for template::element::create for more info.
param_type is one of the following:
'onevalue' - The parameter has one value.
'onelist' - The parameter is a list of values.
'multilist' - The parameter is a list of lists of values.
param_source is one of the following:
'literal' - The value parameter is treated literally
'eval' - The value parameter is a block of Tcl code that will be evaluated to produce the actual value(s) for the form widget param.
'query' - The value parameter is a SQL query which returns a datasource corresponding to the actual value(s) for the form widget param.
To create a pick list of MIME types for the 'mime_type' attribute of the 'content revision' content type:
begin -- register the attribute to a pick list cm_form_widget.register_attribute_widget( content_type => 'content_revision', attribute_name => 'mime_type', widget => 'select', is_required => 't' ); -- set the 'options' list cm_form_widget.set_attribute_param_value( content_type => 'content_revision', attribute_name => 'mime_type', param => 'options', param_type => 'multilist', param_source => 'query', value => 'select label, map.mime_type from cr_mime_types types, cr_content_mime_type_map map where types.mime_type = map.mime_type and content_type = :content_type order by label' ); -- set the 'size' param cm_form_widget.set_attribute_param_value( content_type => 'content_revision', attribute_name => 'mime_type', param => 'size', param_type => 'onevalue', param_source => 'eval', value => 'a_tcl_proc_that_gets_the_pick_list_size' ); end; / show errors
The CMS is able to generate and process metadata forms based on the form widgets registered to each attribute of a content type. If the metadata forms are not sufficient, custom forms can be supplied instead.
Generating the metadata forms for creating content items and adding revisions is done by calling the Tcl procedure:
content::get_revision_form db content_type item_id form_name
The function generates a form based on form widgets associated with the content type's attributes. If the item_id is null, then an item_id will be generated automatically.
Example:
# a metadata form for creating new "book report" content types. form create create_book_report element create create_book_report item_id -datatype integer set db [ns_db gethandle] content::get_revision_form $db book_report $item_id create_book_report ns_db releasehandle $db if { [form is_request create_book_report] } { query item_id onevalue "select acs_object_id_seq.nextval from dual" element set_properties create_book_report item_id -value $item_id }
Processing the metadata forms for creating content items and adding revisions is done by calling the Tcl function:
set revision_id [content::process_revision_form form_name content_type item_id db]
The function creates an instance of a basic revision, and then inserts rows into each extended attribute related to that content type. The function returns the ID of the revision that was just created.
Example:
# process a metadata form for adding a revision to "book report" content types if { [form is_valid add_revision] } { form get_values add_revision item_id set db [ns_db gethandle] set revision_id [content::process_revision_form add_revision book_report $item_id $db] ns_db releasehandle $db template::forward "view_book_report_revision.acs?revision_id=$revision_id" }
The function content::create_form_element may be used to automatically generate a form element based on the registered form widget for the element. This function is useful if you wish to create a custom form for your content type, while still relying on the automatically generated widgets (as discussed above) for some elements.
The function signature is as follows:
proc content::create_form_element { db form_name attribute_name args } { ... }
The parameters to the function are as follows:
Parameter | Purpose |
---|---|
db | The database handle to be used for querying |
form_name | The name of the form to which the element will be appended. The form must have been previously created with the form create statement. |
attribute_name | The name of the attribute for which the form element is to be created. The form element will have the same name as the attribute. |
The function also accepts the following switches:
Switch | Value | Purpose |
---|---|---|
-revision_id | A revision id, integer | The id of the revision which will be used to determine the value for the attribute. This revision will also be used to discover the content type for the item. |
-item_id | An item id, integer | The id of the item whose live revision will be used to determine the value for the attribute. |
-content_type | An object type | The content type of the object to which the attribute belongs |
any other switch | A value appropriate for the switch | Any other switches will be passed directly to the element create statement. |
All the switches above are optional; however, at least one of the -content_type, -revision_id or -item_id must be specified (in order for the function to determine the content type of the object).
If -revision_id or -item_id are specified, the value of the created form element will be selected from the specified revision in the database.
Note that content::create_form_element will not automatically perform DML for you in order to update the database; the DML must be performed manually in your custom form.
content::create_form_element $db my_form width -revision_id $revision_id
The above code will append a new element, called "width" to the form named "my_form". It will use the database handle contained in $db and the revision id specified in $revision_id in order to display the default value for the element.
The generic index page, located at /cms/modules/items/index is simply a skeleton layout that includes all available information components (see next section). (The released system will allow the administator to specify the components shown to each user of the system).
In cases where the generic page is inadequate, you can define your own custom information page at /cms/modules/items/custom/<content_type>/index. Whenever the generic index page is requested, the system checks for the existence of a custom page and redirects to it if it is found. Note that from there you may link to any number of additional custom display pages, stored in the same directory or elsewhere. The only required parameter to your custom page should be item_id.
Many applications of the content repository require that content items be related to each other as well as to other classes of objects. Examples include:
Content to non-content object: User portraits are linked to specific users.
Content to content: An article may be linked to any number of photos or charts that are embedded in the article.
Content within content: A long article is divided into multiple sections, each of which is intended for separate display.
Multiple content items to a category: News stories may be linked to other stories on the same topic.
When relating content types, it is important to establish whether your related items of content can exist separately of each other, such as an article and piece of stock footage or photography, or whether the one of the content items should exist only within the context of another, as in the example from above of a sectioned article with individual portions meant for separate display. We refer to these latter relationships as parent-child relationships. The former can be generically grouped as Item-Object Relationships; relationships between items of content to non-content objects (example 1) would also fall under this category.
Of the above examples, the first three types of relationship are handled by the content_type package API, and the last managed through CMS itself.
Define item-object relationships with the content_type.register_relation_type API:
procedure register_relation_type ( content_type in cr_type_relations.content_type%TYPE, target_type in cr_type_relations.target_type%TYPE, relation_tag in cr_type_relations.relation_tag%TYPE default 'generic', min_n in integer default 0, max_n in integer default null );
content_type refers to the name of the content type from which the relationship originates.
target_type takes the name of the object type to which the content is related.
relation_tag accepts a simple token identifier used in distinguishing relationships
min_n and max_n refer to the minimum/maximum relationships of this type required before the item of content goes live.
After a relationship between one content type and another object type (content or not) has been registered, you may use content_item.is_valid_relation to confirm potential relationships.
Parent-child relationships are also registered using the content_type package API:
procedure register_child_type ( parent_type in cr_type_children.parent_type%TYPE, child_type in cr_type_children.child_type%TYPE, relation_tag in cr_type_children.relation_tag%TYPE default 'generic', min_n in integer default 0, max_n in integer default null );
The parameters for content_type.register_child_type are largely analagous to those for content_type.register_relation_type , except parent_type and child_type must both be content types ( content_revision or a sub-class of it). content_item.is_valid_relation can also be used to verify the validity of a potential parent-child relationship.
[This document is still under construction]
Permissions provide a way of answering the question, "may the user X perform some action Y on an object Z" ? The CMS UI provides forms for viewing and maintaining permissions, as well as a set of standard permissions which should be useful for web publishing applications. For a more complete description of the various permissions, see the CMS developer guide.
To view permissions on folders, select the folder on the tree and click the "Folder Attributes" link. To view permissions on items, simply select the item in the folder and scroll down to the bottom of the page. In both cases, the permissions listing for the item/folder appears on the screen:
To grant permissions to another user, mark the user on the clipboard and click "[ Grant ] more permissions to a marked user". You will only be allowed to grant permissions which you already possess, unless you have the "Modify Any Permissions" privilege.
To edit permissions for a particular user, click the icon next to the user's name. The icon will not be visible unless you are allowed to edit permissions for that particular user.
In both cases, a permission editing form will appear on the screen:
The privileges are arranged on the form in a tree-like hierarchy; possession of a parent permission entails the possession of all of its child permissions, as well. For example, a user with "Admin-level Read" would also have read access to anything requiring "User-level Read."
Check any permissions that you wish to grant to the user and uncheck any permissions that you wish to revoke. If you select "Yes" for the "Apply changes to child items and subfolders" option, your changes will affect the current item or folder, all the items in the folder, all subfolders of the folder, all the items in the subfolders, etc. If you select "No", only the current item or folder will be affected.
Note that if you revoke a permission, all of its descendants will remain granted to the user. For example, if you revoke the "Admin-Level Read" permission from a user, the user will retain the "User-level Read" permission.
Also note that you may not be able to modify some permissions on certain items; for example, you may not revoke somebody's "Administrator" permission if you yourself do not possess the "Administrator" permission on the item.
This document contains a listing of Content Management tasks and the required permissions to perform them. The tasks are organized by modules and then main sections/pages within those modules.
This document is currently under construction.
Editing
Sub-Items
Publishing
Permissions
Search
Subject Keywords
Users
Workflow
Clipboard
Action | Required Permission(s) | Other Requirement(s) |
---|---|---|
Add this content type to the clipboard |
| |
[ Register Widget | Edit Widget | Unregister Widget ] |
|
|
Register marked templates to this content type |
| |
Unregister template |
| |
Make this template the default |
|
|
Register/Unregister a new item relation type |
| |
Register/Unregister a new child relation type |
| |
Register/Unregister MIME type |
|
|
Grant more permissions to a marked user |
| |
Alter user permissions |
|