Index: openacs-4/packages/acs-content-repository/www/doc/design.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/design.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/design.adp 16 Sep 2014 20:51:10 -0000 1.1.2.1 @@ -0,0 +1,68 @@ + +{/doc/acs-content-repository {Content Repository}} {Content Repository Design} +Content Repository Design + + + +

Content Repository Design

+ACS Documentation : Content Repository +

I. Essentials

II. Introduction

Serving content is a basic function of any web site. +Common types of content include:

Note that the definition of content is not limited to what is +produced by the publisher. User-contributed content such as +reviews, comments, or message board postings may come to dominate +active community sites.

Regardless of its type or origin, it is often useful for +developers, publishers and users to handle all content in a +consistent fashion. Developers benefit because they can base all +their content-driven applications on a single core API, thereby +reducing the need for custom (and often redundant) development. +Publishers benefit because they can subject all types of content to +the same management and production practices, including access +control, workflow, categorization and syndication. Users benefit +because they can enjoy a single interface for searching, browsing +and managing their own contributions.

The content repository itself is intended only as a +common substrate for developing content-driven applications. It +provides the developer with a core set of content-related +services:

As a substrate layer, the content repository is not intended to +ever have its own administrative or user interface. ACS modules and +custom applications built on the repository remain responsible for +implementing an appropriate interface. (Note that the ACS Content +Management System provides a general interface for interacting with +the content repository).

III. Historical Considerations

The content repository was originally developed in the Spring of +2000 as a standalone data model. It was based on an earlier custom +system developed for an ArsDigita client. Many of the principle +design features of the original data model were also reflected in +the ACS Objects system implemented in the ACS 4.0 core. The content +repository was subsequently rewritten as an extension of ACS +Objects.

V. Design Tradeoffs

The content repository is a direct extension of the core ACS +Object Model. As such the same design tradeoffs apply.

The content repository stores all revisions of all content items +in a single table, rather than maintaining separate tables for +"live" and other revisions. The single-table approach dramatically +simplifies most operations on the repository, including adding +revisions, marking a "live" revision, and maintaining a full +version history. The drawback of this approach is that accessing +live content is less efficient. Given the ID of a content item, it +is not possible to directly access the live content associated with +that item. Instead, an extra join to the revisions table is +required. Depending on the production habits of the publisher, the +amount of live content in the repository may be eclipsed by large +numbers of infrequently accessed working drafts. The impact of this +arrangement is minimized by storing the actual content data in a +separate tablespace (preferably on a separate disk) from the actual +revisions table, reducing its size and allows the database server +to scan and read it more efficiently.

VI. Further Reading

The Object Model provides a +graphic overview of the the how the content repository is designed. +The model links to pages of the API Guide that describe individual +objects. The Developer Guide describes how to address common +development tasks using the content repository.


karlg@arsdigita.com
+Last Modified: $Id: design.html,v 1.1.1.1 2001/03/13 22:59:26 ben +Exp $ + Index: openacs-4/packages/acs-content-repository/www/doc/index.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/index.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/index.adp 16 Sep 2014 20:51:11 -0000 1.1.2.1 @@ -0,0 +1,37 @@ + +{/doc/acs-content-repository {Content Repository}} {ACS Content Repository} +ACS Content Repository + + + +

ACS Content Repository

ACS Documentation

karlg@arsdigita.com
+Last Revised: $Id: index.adp,v 1.1.2.1 2014/09/16 20:51:11 gustafn Exp $ + Index: openacs-4/packages/acs-content-repository/www/doc/install.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/install.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/install.adp 16 Sep 2014 20:51:11 -0000 1.1.2.1 @@ -0,0 +1,63 @@ + +{/doc/acs-content-repository {Content Repository}} {Content Repository: Installation} +Content Repository: Installation + + + +

Installing the Content Repository

Content Repository

The content repository is a part of the core data model of ACS +4.0 and greater, and is loaded automatically as part of the ACS +installation process.

If you wish to install the content repository in a database +schema outside the context of ACS, the following instructions +apply.

First install the data model and PL/SQL API:

    +
  1. Obtain the latest distribution of ACS.
  2. Run the SQL script +packages/acs-kernel/sql/acs-kernel-create.sql to load the +core ACS Objects data model.
  3. Run the SQL script +packages/acs-workflow/sql/acs-workflow-create.sql to load +the workflow package.
  4. Run the SQL script +packages/acs-workflow/sql/acs-content-repository-create.sql +to load the content repository itself.
  5. +

Java

In additional to SQL and PL/SQL, the content repository +implements a limited set of key methods in Java. The XML import and +export methods are dependent on Oracle's XML Parser for Java v2, +available from the Oracle Technology Network:

http://technet.us.oracle.com/tech/xml/parser_java2/index.htm

To load the XML parser, download and untar the distribution. +Load the class package lib/xmlparserv2.jar into Oracle +from a shell prompt:

+$ loadjava -user user/password xmlparserv2.jar
+

Finally, load the SQLJ files in +packages/acs-content-repository/java:

+$ loadjava -user user/password -resolve *.sqlj
+

Installation of the data model and API should now be +complete.

Intermedia

The content repository relies on an Intermedia with the INSO +filtering option to search text within a wide variety of file +formats, including PDF and Microsoft Word. When the index on the +content column of cr_revisions is built, the INSO +filter automatically detects the file type of each entry and +extracts all available text for indexing.

If your searches are not returning any results even after +rebuilding the index, INSO filtering may be silently failing. You +can verifying this by checking for entries in the +ctx_user_index_errors view following an alter +index statement.

If you experience errors on a UNIX system, check the +following:

    +
  • The operating system user running the Oracle database must have +execute permission on the files +$ORACLE_HOME/ctx/lib/*.flt.
  • The directory $ORACLE_HOME/ctx/lib must be in the +$PATH environment variable of the operating system user +running the Oracle database.
  • The directory $ORACLE_HOME/ctx/lib must be in the +$LD_LIBRARY_PATH of the operating system user running the +Oracle database.
  • The LD_LIBRARY_PATH environment variable must be +specified in the entry for PLSExtProc in the +$ORACLE_HOME/network/admin/listener.ora. For example:
  • +
+    (SID_DESC =
+      (SID_NAME = PLSExtProc)
+      (ORACLE_HOME = /ora8/m01/app/oracle/product/8.1.6)
+      (ENVS = LD_LIBRARY_PATH=/ora8/m01/app/oracle/product/8.1.6/lib:/usr/lib:/lib:/usr/openwin/lib:/ora8/m01/app/oracle/product/8.1.6/ctx/lib)
+      (PROGRAM = extproc)
+    )
+

If your searches are still failing even after following these +instructions, try a simple test case +to determine whether the problem has something to do with the +content repository data model itself.


karlg@arsdigita.com
+Last revised: $Id: install.html,v 1.1.1.1 2001/03/13 22:59:26 ben +Exp $ + Index: openacs-4/packages/acs-content-repository/www/doc/intermedia.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/intermedia.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/intermedia.adp 16 Sep 2014 20:51:11 -0000 1.1.2.1 @@ -0,0 +1,70 @@ + +{/doc/acs-content-repository {Content Repository}} {Content Repository: Testing Intermedia} +Content Repository: Testing Intermedia + + + +

Testing Intermedia

Content Repository

Even if you follow the instructions in the installation notes, content searches may +inexplicably fail to work. This document describes how to create a +simple test case independent of the content repository to verify +that Intermedia is indeed functioning properly.

Create a document table

Create a simple table to hold some test documents:

+create table cr_test_documents ( 
+  doc_id    integer primary key, 
+  author    varchar2(30), 
+  format    varchar2(30), 
+  title     varchar2(256), 
+  doc       blob 
+);
+

Create an Intermedia preference to specify INSO filtering:

+begin
+  ctx_ddl.create_preference
+  (
+    preference_name => 'CONTENT_FILTER_PREF',
+    object_name     => 'INSO_FILTER'
+  );
+

If this preference has already been created, this step will +cause an error that you can ignore.

Create an Intermedia index on the test table with INSO +filtering:

+create index cr_test_documents_idx on cr_test_documents ( doc )
+  indextype is ctxsys.context
+  parameters ('FILTER content_filter_pref' );
+

Load test documents

You can use SQL*Loader to load some documents into the test +table. First create a control file named +cr-test-docs.ctl:

+load data
+INFILE 'cr-test-docs.data'
+INTO TABLE cr_test_documents
+APPEND
+FIELDS TERMINATED BY ','
+(doc_id SEQUENCE (MAX,1),
+ format,
+ title,
+ ext_fname FILLER CHAR(80),
+ doc LOBFILE(ext_fname) TERMINATED BY EOF)
+

Copy any number of documents (Microsoft Word, PDF, text, HTML, +etc.) to the file system of your database server. Create a data +file with an entry for each document you would like to load. This +is simply a comma-separated text file:

+word, Simple Story,sample-docs/simple.doc,
+excel, Simple Spreadsheet,sample-docs/simple.xls
+

Load the documents from the command line:

+$ sqlldr userid=cms/cms control=cr-test-docs.ctl log=cr-test-docs.log
+
+SQL*Loader: Release 8.1.6.2.0 - Production on Thu Nov 9 13:36:56 2000
+
+(c) Copyright 1999 Oracle Corporation.  All rights reserved.
+
+Commit point reached - logical record count 2
+

Test search

Once the documents have been loaded, rebuild the index and run +some test queries:

+SQL> alter index cr_test_documents_index rebuild online parameters ('sync');
+SQL> select score(1), doc_id from cr_test_documents 
+       where contains(doc, 'cars', 1) > 0;
+
+  SCORE(1)     DOC_ID
+---------- ----------
+         4          1
+

karlg@arsdigita.com
+Last revised: $Id: intermedia.html,v 1.1.1.1 2001/03/13 22:59:26 +ben Exp $ + Index: openacs-4/packages/acs-content-repository/www/doc/object-model.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/object-model.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/object-model.adp 16 Sep 2014 20:51:11 -0000 1.1.2.1 @@ -0,0 +1,27 @@ + +{/doc/acs-content-repository {Content Repository}} {Content Repository: Object Model} +Content Repository: Object Model + + + +

Object Model

Content Repository

The content repository is an extension of the ACS Object Model. +The following diagram illustrates the relationship among the +standard object types defined by the content repository (click on a +box to view a description and API summary for a particular object +type):

+ +

Note that content revisions and content items inherit separately +from the root of the object model. Each item may be related to one +or more revisions, but they are fundamentally different types of +objects.

Also important to note is the relationship between custom +content types and the rest of the object model. You define new +content types as subtypes of Content Revision, not of Content Item. +This is because new content types are characterized by their +attributes, which are stored at the revision level to make changes +easy to audit. Custom content types typically do not require +additional unaudited attributes or methods beyond those already +provided by the Content Item type. It is thereful almost never +necessary to create a custom subtype of Content Item itself.


karlg@arsdigita.com
+Last revised: $Id: object-model.html,v 1.1.1.1 2001/03/13 22:59:26 +ben Exp $ + Index: openacs-4/packages/acs-content-repository/www/doc/requirements.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/requirements.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/requirements.adp 16 Sep 2014 20:51:11 -0000 1.1.2.1 @@ -0,0 +1,326 @@ + +{/doc/acs-content-repository {Content Repository}} {Content Repository Requirements} +Content Repository Requirements + + + +

Content Repository Requirements

+Karl Goldstein (karlg@arsdigita.com)
Revision History

VI.A Requirements: Data Model

5.0 MIME Types

The content repository must be able to store objects in any +format, both text and binary. MIME types provide a standard set of +codes for identifying the file format of each content item. For the +purpose of data integrity, the repository must have a canonical +list of MIME types that may be assigned to content items.

10.0 Content Types

A content type is characterized by a set of attributes +that may be associated with a text or binary content object. +Attributes are stored separately from their associated content +object, and as such may be indexed, searched, sorted and retrieved +independently. For example, attributes of a press release may +include a title, byline, and publication date.

The data model must support storage of descriptive information +for each content type:

+

+10.10 Content types must be associated with unique +keyword identifiers, such as press_release, so they can be +referenced in data tables, queries and procedural code.

+10.20 Content types must be associated with singular and +plural descriptive labels, such as Press Release and +Press Releases, to simplify user recognition.

+10.20 Content types may specify any number of +attributes. Attribute values are simple strings or +numbers.

+10.30 Content types may inherit attributes from any other +other content type. For example, a regional press release may be a +subtype of the press release type. Regional press releases have a +region attribute in addition to the characteristics of a +regular press release.

+10.40 Part of the definition of a content type may +include a description of the parent-child relationships allowed for +items of this type. For example, a Press Release may contain +one or more items of type Image, but it should not contain +any items of type Internal Financial Status Report.

+10.60 A content type definition may include a list of +allowed file MIME types for items of this type.

+10.70 A content type definition may include a list of +tokens to identify or flag relationships with other items. For +example, the content type definition for a chapter of a reference +manual may include the tokens next, previous and +see_also. Each type of relationship may include a minimum +and/or maximum number of relationships of this type that are +required for an item to be published.

+

20.0 Content Items

Items are the fundamental building blocks of the content +repository. Each item represents a distinct text or binary content +object that is publishable to the web, such as an article, report, +message or photograph. An item my also include any number of +attributes with more structured data, such as title, source, byline +and publication date.

Content items have the following persistent characteristics +which the data model must support:

+

+20.10 Content items must have a simple unique identifier +so they can be related to other objects in the system.

+20.20 Each content item consists of a set of attributes +and a single text or binary object.

+20.25 All content items are associated with a few basic +attributes to facilitate searching and development of browser +interfaces to the content repository:

    +
  • A title
  • A brief description or summary
  • An author or contributor
  • A publication or posting date
  • A distinguished URL at which an item may be +accessed.
  • A MIME type
  • +

+20.30 Each content item must be an instance of a +particular content type. The content type +defines the attributes associated with the content item, in +addition to the basic ones described above.

+20.40 A content item must have a unique, persistent URL +(Uniform Resource Locator) by which it is publicly accessible, such +as /press-releases/products/widget. To facilitate moving +of items within the repository, the item itself should only be +associated with the "tail" of the url, such as widget. The +absolute URL of the item is determined by its location within the +repository (See Content +Organization).

+20.50 It must be possible to specify the language of each +item.

+20.60 It must be possible to maintain a revision history +for both the attributes and the text or binary object associated +with a content item.

+20.70. There must be a flexible mechanism for +implementing access control on individual items, based on granting +of permissions to groups or individual users.

+20.80. A content item may be associated with any number +of workflows.

+20.90. Content items may themselves be "containers" or +"parents" for other content items. For example, an Article +may contain multiple Sections.

+20.95 Each item may be associated with any number of +related objects. The type and number of relationships must be +constrained by the content type of the item (See 10.70 above).

+

30.0 Content +Revision

As mentioned above, each content item may be associated with any +number of revisions. The data model for revisions must support the +following:

+

+30.10. A revision consists of the complete state of the +item as it existed at a certain point in time. This includes the +main text or binary object associated with the item, as well as all +attributes.

+30.20. The data model must be extensible so that +revisions for all content types (with any number of attributes) may +be stored and retrieved efficiently.

+

40.0 Organization of +the Repository

+

+40.10. The data model must support the hierarchical +organization of content items in a manner similar to a file +system.

+40.20. The URL of a content item should reflect its +location in the hierarchy. For example, a press release with the +URL /press-releases/products/new-widget is located at the +third level down from the root of the hierarchy.

+40.20.5 Content +Folder.

A folder is analogous to a folder or directory in a +file system. It represents a level in the content item hierarchy. +In the previous example, press-releases is a folder under +the repository root, and products is folder within that. +The description of a folder may include the following +information:

+

+40.20.5.10. A URL-encoded name for building the path to +folders and individual items within the folder.

+40.20.5.20. A pointer to a content item that may serve as +the "index" for the folder (i.e. the item that is served when the +URL of the folder itself is accessed).

+40.20.5.30. A set of constraints on the number and type +of content items that may be stored in the folder.

+

+40.30. It must be possible to create symbolic links or +shortcuts to content items, so they may be presented at more than +one URL or branch of the hierarchy.

+

+40.30.5 Content Symbolic +Link.

A symbolic link is +analogous to a symlink, alias or shortcut in a file system. The +description of a symbolic link must include the following +information:

+40.30.5.10. A URL-encoded +name for the symbolic link. As for folders and items, this only +represents the "tail" of the URL, with the full URL being +determined by the folder in which the link is located.

+40.30.5.20. A pointer to a +target item which the symbolic link references..

+40.30.5.30. A title or +label, which may be different from the title or label of the target +item.

+
+

+50.0 Content Template.

The content repository should provide a means of storing and +managing the templates that are merged with content items to render +output in HTML or other formats. Templates are assumed to be text +files containing static markup with embedded tags or code to +incorporate dynamic content in appropriate places. The data model +requirements for templates are a subset of those for content +items.

Because they typically need to reference a specific attributes, +a template is typically specific to a particular content types and +its subtypes.

VI.B Requirements: Stored Procedure API

100.10 MIME Types

Since a MIME type is a required attribute of each content item, +the repository must be capable of managing a list of recognized +MIME types for ensuring appropriate delivery and storage of +content.

+

+100.10.10. Register a MIME type

+100.10.20. Set the description of a MIME type

+100.10.30. Get the description of a MIME type

+100.10.40. Determine whether a MIME type is text or +binary

+100.10.50. Get a list of registered MIME types

+100.10.60. Unregister a MIME type

+

It is important to note that the role of MIME types in the +content repository is simply to describe the general file format of +each content item. Neither the data model nor the API support the +full range of allowed parameters for the general MIME types such as +text/plain.

100.20 Locales

The repository must have access to a list of recognized locales +for the purpose of publishing content items in multiple languages +and character sets.

All content in the repository is stored in UTF-8 to facilitate +searching and uniform handling of content. Locales may be specified +as user preferences to configure the user interface in the +following ways:

    +
  • language of content (when items are available in multiple +languages).
  • language of system messages (form labels, warnings, menu links, +etc.).
  • character set (text content converted from UTF-8 to the +specified character set).
  • number, date and currency format.
  • choice of layout, including templates, graphics and other +resources.
  • +

Functional requirements for locales include:

+

+100.20.10. Register a locale, including language, +territory and character set.

+100.20.20. Get the language of a specified locale.

+100.20.10. Get the character set code of a specified +locale using either Oracle or WETF/ISO/ANSI codes.

+100.20.30. Get the number, date and currency format of a +specified locale.

+100.20.40. Convert a text content item to a specified +locale (character set).

+100.20.50. Get a list of registered locales.

+100.20.60. Unregister a locale.

+

100.30 Content Types

+

+100.30.10. Create a content type, optionally specifying +that it inherits the attributes of another content type. Multiple +inheritance is not supported.

+100.30.20. Get and set the singular and plural proper +names for a content type.

+100.30.30. Create an attribute for a content type.

+100.30.40. Register a content type as a container for +another content type, optionally specifying a minimum and maximum +count of live items.

+100.30.50. Register a content type as a container for +another content type, optionally specifying a minimum and maximum +count of live items.

+100.30.60. Register a set of tags or tokens for labeling +child items of an item of a particular content type.

+100.30.70. Register a template +for use with a content type, optionally specifying a use context +("intranet", "extranet") which the template is appropriate to +use.

+100.30.80. Register a particular type of workflow to +associate with items of this content type by default.

+100.30.90. Register a MIME type as valid for a content +type. For example, the Image content type may only allow GIF +and JPEG file formats.

+100.30.95 Register a relationship with another type of +object, specifying a token or name for the relationship type as +well as a minimum and/or maximum number of relationships of this +type that are required for the item to be published.

+

100.40 Content Items

+

+100.40.10. Create a new item, specifying a parent context +or the root of the repository by default.

+100.40.15. Rename an item.

+100.40.17. Copy an item to another location in the +repository.

+100.40.20. Move an item to another location in the +repository.

+100.40.30. Get the full path (ancestry of an item) up to +the root.

+100.40.35. Get the parent of an item.

+100.40.40. Determine whether an item may have a child of +a particular content type, based on the existing children of the +item and the constraints on the content type.

+100.40.45. Label a child item with a tag or token, based +on the set of tags registered for the content type of the container +item.

+100.40.50. Get the children of an item.

+100.40.55. Get the children of an item by type or +tag.

+100.40.60. Establish a generic relationship between any +object and a content item, optionally specifying a relationship +type.

+100.40.70. Create a revision.

+100.40.80. Mark a particular revision of an item as +"live".

+100.40.83. Specify a start and end time when an item +should be available.

+100.40.85. Clear the live revision attribute of an item, +effectively removing it from public view.

+100.40.90. Get a list of revisions for an item, including +modifying user, date modified and comments.

+100.40.95. Revert to an older revision (create a new +revision based on an older revision).

+

100.50 Content Folders

The repository should allow for hierarchical arrangement of +content items in a manner similar to a file system. The API to meet +this general requirement focuses primarily on content folders:

+

+100.50.10. Create a folder for logical groups of +content items and other folders. The folder name becomes part of +the distinguished URL of any items it contains. Folders may be +created at the "root" or may be nested within other folders.

+100.50.20. Set a label and description for a folder.

+100.50.30. Get the label and description for a +folder.

+100.50.40. Get a list of folders contained within a +folder.

+100.50.50. Move a folder to another folder.

+100.50.60. Copy a folder to another folder.

+100.50.70. Create a symbolic link to a folder from +within another folder. The contents of the folder should be +accessible via the symbolic link as well as the regular path.

+100.50.80. Tag all live item revisions within a folder +with a common version descriptor (i.e. 'Version 1.0' or 'August 1 +release'), for the purpose of versioning an entire branch of the +site. Folder objects themselves are not eligible for +versioning, since they are solely containers and do not have any +content other than the items they contain.

+100.50.90. Delete a folder if it is empty.

+

Note that folders are simply a special type of content item, and +as such may receive the same object services as items, (namely +access control and workflow). In addition to the file-system +analogy afforded by folders, any type of content item may serve as +a contain for other content items (see below).

Workflow

The repository must offer integration with a workflow package +for managing the content production process.

100.60 Categorization

The repository must support a common hierarchical taxonomy of +subject classifications that may be applied to content items.

+

+100.60.10. Create a new subject category.

+100.60.20. Create a new subject category as the child of +another subject category.

+100.60.30. Assign a subject category to a content +item.

+100.60.40. Remove a subject category from an item.

+100.60.50. Get the subject categories assigned to a +content item.

+

Search

The repository must have a standard means of indexing and +searching all content.

Access Control

The repository must have a means of restricting access on an +item-by-item basis.

VI.C Requirements: Presentation Layer API

The presentation layer must have access to a subset of the +stored procedure API in order to search and retrieve content +directly from the repository if desired.

Revision History

+ + + + + + + + + + + +
AuthorDateDescription
Karl Goldstein9 August 2000Initial draft.
Karl Goldstein22 August 2000Added to API section.
Karl Goldstein19 September 2000Added data model requirements, revised API requirements, +numbered all items.
Karl Goldstein21 September 2000Add requirements for relationships among content items and +other objects.

karlg@arsdigita.com
+Last Modified: $Id: requirements.html,v 1.2 2003/12/11 21:39:47 +jeffd Exp $ + Index: openacs-4/packages/acs-content-repository/www/doc/todo.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/todo.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/todo.adp 16 Sep 2014 20:51:11 -0000 1.1.2.1 @@ -0,0 +1,75 @@ + +{/doc/acs-content-repository {Content Repository}} {} + + + + +

To Do List for Content Management System

+
+Documentation
+
+Write ASAP.
+
+Sign In/Out
+
+--Eventually need to use regular acs40 API (maintain existing interface)
+
+Work Items 3
+
+--Display deadlines highlighted depending on whether the deadline has
+  passed
+--Add ability to check items in and out in addition to simply finishing
+  enabled tasks.
+
+Site Map
+
+--Tree widget is buggy (not updating correctly on delete, not showing blue
+                        arrows in proper context, etc.) 1-Stas
+--Improve design of folder listing (sortable by name, date, size, mod_time) Michael
+--Symlink title is confusing (Stas)
+--Ideally bookmark graphics show change to show items that are currently 
+  marked.
+
+Items
+
+--UI around each item needs polishing (better display of revisions etc.) 
+--support for display and editing of additional simple attributes 2
+--for now just allow assignment of one template. 1-Karl
+--We currently have no way of setting access controls (also applies to 
+   folders). 1
+
+Content Types
+
+--Not much to do here, seems OK.
+--Need UI for creating content types, adding attributes, etc. (3)
+
+Subject Categories
+
+--Need to reintegrate simple category table (depends on message catalog)
+  Previous UI was functional, should be reusable.
+-- 1
+
+Message Catalog
+
+--Remove as a module for now.
+
+Users
+
+--Should display the party hierarchy here, with tools for adding/removing
+  users.  Parties and usersshould be markable to the clipboard so they can 
+  be used in building workflow contexts and access control lists.
+-- 2
+
+Workflows
+
+--index.tcl: Display a list of available workflows, add/remove users from
+the eligible list for each transition, etc.
+--reintegration with notifications!
+
+Clipboard 
+
+--think about improving UI for this. 2
+
+

Last Modified: $Id: todo.html,v 1.1.1.1 2001/03/13 22:59:26 ben +Exp $

+ Index: openacs-4/packages/acs-content-repository/www/doc/tutorial.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/tutorial.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/tutorial.adp 16 Sep 2014 20:51:11 -0000 1.1.2.1 @@ -0,0 +1,715 @@ + +{/doc/acs-content-repository {Content Repository}} {ACS Content Repository Tutorial} +ACS Content Repository Tutorial + + + +

How to use the content repository

+by Jade Rubick

Why use the content repository?

Let's say you're a developer making a package for OpenACS. +You've heard statements like, "every package should use the content +repository", or maybe a developer has suggested that you use it. Or +maybe you just stumbled across it. Why would you want to spend your +time reading this document and wasting a good afternoon when you +could get started coding right away?

The simple answer is that the content repository (CR) gives you +many different things for free:

    +
  • support for versioning
  • hierarchical organization of items
  • permissions
  • extending your tables dynamically
  • +
+The content repository was created to solve many of the common +problems we as developers face. +

State of this document

+This is not a perfect introduction to the content repository. But +hopefully it will be a skeleton that can be developed further into +an excellent, helpful tutorial for people new to the content +repository. +

Introduction

For the sake of an example, I'm going to use a Tasks +application. This application will keep track of all the tasks of +an organization, deadlines for those tasks, and who needs to work +on them.

The reason I might be interested in using the content repository +(CR) in this case is that I can keep track of all the changes to a +particular Task, so that if someone changes the deadline on an +item, I can see what the original deadline was. In addition, I as a +developer would like to have sub-tasks, and sub-sub-tasks, so I can +have a whole hierarchy of things that need to be accomplished. Big +tasks can be sub-divided so that several people can each do their +particular parts.

So I decide to create a Tasks table. Each of these Tasks has +various information associated with it, such as deadlines, +descriptions of what needs to be accomplished, and so on:

+Task
+          Title
+          Description
+          Task Number
+        
+

Overview

First of all, let's get some terminology out of the way. Columns +of a table are referred to as attributes in content +repository-speak.

+The steps to set up your data model are as follows: +
    +
  1. What attributes do you want?
  2. Define tables
  3. Describe attributes
  4. +

What attributes do you want?

The first step is to decide on what part of a Task you'd you'd +like to have under revision control, and what portion you'd like to +have just one version of. In our case, the only thing we wouldn't +want under version control is the Task Number. This will be a +unique identifier for the task, and we don't want that changing +every time someone edits it.

For our simple example:

+          Title - want versions
+          Description - want versions
+          Task Number - do NOT want versions
+        
+

Define tables

You will have two tables: one with versioned attributes, and one +without versioned attributes.

+Convention: often, developers will name the first table +by what it is (in my case pm_tasks), and the second, +versioned table by the same name, but with _revisions at the end. +Thus, I'll name my second table pm_tasks_revisions.

+This is actually very easy: +

Versioned portion:

+            create table pm_tasks_revisions (
+            task_revision_id
+            integer 
+            constraint pm_tasks_revisions_id_pk
+            primary key
+            constraint pm_tasks_revisions_id_fk
+            references cr_revisions(revision_id)
+            on delete cascade,
+            title
+            varchar(100),
+            description
+            varchar(4000)
+            );
+          
+

Unversioned portion:

+            create table pm_tasks (
+            task_id
+            integer
+            constraint pm_tasks_id_pk
+            primary key
+            constraint pm_tasks_id_fk
+            references cr_items(item_id)
+            on delete cascade,
+            task_number
+            integer
+            )
+          
+

One thing you have to be careful of when creating these tables +is that there are no columns that have the same names as any of the +columns in the cr_items and cr_revisions +tables. For example, you can't call you key on the +pm_tasks_revisions table revision_id. Why? There are +some views that are automatically generated that combine these +tables for you, but they won't be created if the names conflict. +I'll describe what these views are later, but they are useful. You +were warned.

Notice that each table uses as its primary key a reference to +either the cr_revisions table or the +cr_items table. A content item is basically +just some content: either text or binary data. The contents +revisions table keeps track of which version from the +tasks_revisions table is the most current, and which one is +live.

All this is going inside the +sql/postgresql/project-manager-create.sql file. Your +name will be different of course.

Describe attributes

After we've created the two tables, we need to let the content +repository know that we have a new type of structured data that we +are storing in the content repository. Tasks are a "content type", +because they have data associated with them, such as when they are +due, and what needs to be done.

I thus need to to

+          --create the content type
+          select content_type__create_type (
+          'pm_task', -- content_type   
+          'content_revision', -- not sure what this is
+          'Task', -- pretty_name
+          'Tasks', -- pretty_plural
+          'pm_tasks_revisions', -- table name
+          'task_id', -- id_column
+          'content_revision.revision_name'
+          );
+        
+

You then need to add in all the attributes, so that the content +repository can do some magic things behind the scenes. The content +repository doesn't know about what's inside of the pm_tasks +and pm_tasks_revisions tables, so we teach it:

+          -- add in attributes
+          
+          select content_type__create_attribute (
+          'pm_task', -- content_type
+          'start_date', -- attribute_name
+          'date',     -- datatype (string, number, boolean, date, keyword, integer)
+          'Start date', -- pretty_name
+          'Start dates', -- pretty_plural
+          null, -- sort_order
+          null, -- default value
+          'timestamptz' -- column_spec
+          );
+          
+          select content_type__create_attribute (
+          'pm_task', -- content_type
+          'end_date', -- attribute_name
+          'date',     -- datatype
+          'End date', -- pretty_name
+          'End dates', -- pretty_plural
+          null, -- sort_order
+          null, -- default value
+          'timestamptz' -- column_spec
+          );
+          
+          select content_type__create_attribute (
+          'pm_task', -- content_type
+          'percent_complete', -- attribute_name
+          'number',           -- datatype
+          'Percent complete', -- pretty_name
+          'Percents complete', -- pretty_plural
+          null, -- sort_order
+          null, -- default value
+          'numeric' -- column_spec
+          );
+        
+

+Side effect: once you've created the content type, the +content repository creates a view for you called +pm_tasks_revisionsx. Note the x at the end of the +name. If you're using Postgres, I believe it will also create a +view for you called pm_tasks_revisionsi +

Why are these two views created? the x view is created for +selection, and the i view is created for inserts. They join the +acs_objects, cr_revisions, and our pm_tasks_revisions tables +together. Try viewing them to get an idea of how they might be +useful.

Advanced topic: Creating types and attributes

It is also possible to dynamically create tables, and extend +them with extra columns. You could do this by using create +table or alter table add column statements in +SQL, but this also adds in some meta-data that will be useful to +you. The disadvantage is that you have to call the content +repository API. The advantage is that someday you'll be able to do +really cool stuff with it, like automatically generate interfaces +that take advantage of the new columns and tables you've added. +Another nice thing is that all that messy business of defining your +attributes through the API is taken care of.

+Types is the content repository are another term for +tables, although that doesn't explain it completely. Types are also +kept track of within OpenACS, in the acs_object_types +table, so the system knows about the tables you create, and can do +some intelligent things with them.

A lot of the intelligent things you can do with this +information is still being built. But imagine for example that you +are using the project manager package I've written. You work at an +ice cream company, and every task that is done also has an +associated ice cream flavor with it (yeah, this isn't a good +example, but pay attention anyway). If I've written the project +manager to take advantage of it, when you add in this extra +attribute to the pm_tasks_revisions table, the UI aspects will be +automatically taken care of. You'll be able to select a flavor when +you edit a task, and it will be shown on the task view page. This +is the direction OpenACS development is going, and it will be +really really cool!

First, I'm going to describe how to extend other content +repository tables using the CR API. Then, I'll describe how to set +up your own tables as well:

As you recall from earlier in this page, attributes are just +another term for columns in a table. The Content Repository has a +mechanism for adding and removing columns via the pl/sql API. If +you check your /api-doc: +/api-doc/plsql-subprogram-one?type=FUNCTION&name=content%5ftype%5f%5fcreate%5fattribute +, you'll see that there is a way to extend the columns +programmatically.

Why would you want to do this? For project manager, I decided to +do this because I wanted to customize my local version of the +projects table, to account for company-specific information. That +way, I can have a separate edit page for those types, but not have +a separate table to join against.

+. Instead of doing this: +
+alter table pm_projects add column 
+        target_date  date;
+
+I can do this: +
+select content_type__create_attribute(
+        'pm_project',
+        'target_date',
+        'date',
+        'Target date',
+        'Target dates',
+        null,
+        null,
+        'date'
+);
+
+A very important advantage of this method is that it recreates all +the views associated with the pm_projects table, like pm_projectsx. +If I did an alter table statement, all the views would not contain +the new column. Note that I believe you CAN create foreign key +constraints, by putting them in the column spec (the last column): +
+select content_type__create_attribute(
+        'pm_project',
+        'company_id',
+        'integer',
+        'Company',
+        'Companies',
+        null,
+        null,
+        'integer constraint pm_project_comp_fk references organizations'
+);
+
+I have no idea of whether or not that is supposed to be legal, but +I believe it works. Jun was the one who originally talked about +the +possibility of storing all the revisioned columns in a generic +table. +

How versioning works

+You then need to define a couple of functions, that do all the +nasty work of putting everything in the right tables. The general +idea behind it is that the revisioned information is never changed, +but added to. Here's how it works. When you create a new task, you +call the pm_task__new_task_item function (which we'll +write in a little bit). This function creates both a new content +item, and a new content revision. Information is actually stored in +four tables, believe it or not: cr_revisions, +cr_items, pm_tasks, and +pm_tasks_revisions. The task number is stored in +pm_tasks, the title and description are stored in +pm_tasks_revisions, and some additional information like who +entered the information is stored in cr_revisions and cr_items. +Whenever you make a change to this item, you don't change the table +yourself, but add a revision, using your +pm_task__new_task_revision function (which we'll write +in a little bit). This function adds another revision, but +not another item or cr_item. After you've added another +revision, you'll have two revisions and one item. Two entries in +cr_revisions (and pm_tasks_revisions), and one item in cr_items and +pm_tasks. The cr_revisions table keeps track of which item is the +most recent, and which item is "live". For the edit-this-page +application, for example, this is used to keep track of which +revision to a page is actually being served to users. In your code, +you'll use your pm_tasks_revisionsx view, which joins the +pm_tasks_revisions table with the cr_revisions table (and it might +even join in cr_items -- I forget at the moment). +

Defining your pl/sql functions

+You can see the actual functions used in project manager via the + +CVS browser's entry for project-manager. Note these are a +little more expanded than what I've used in the examples above. +
+select define_function_args('pm_task__new_task_item', 'task_id, project_id, title, description, end_date, percent_complete, estimated_hours_work, estimated_hours_work_min, estimated_hours_work_max, creation_date, creation_user, creation_ip, package_id');
+
+create function pm_task__new_task_item (
+        p_task_id integer,
+        p_project_id integer,
+        p_title varchar,
+        p_description varchar,
+        p_end_date timestamptz,
+        p_percent_complete numeric,
+        p_estimated_hours_work numeric,
+        p_estimated_hours_work_min numeric,
+        p_estimated_hours_work_max numeric,
+        p_creation_date timestamptz,
+        p_creation_user integer,
+        p_creation_ip varchar,     
+        p_package_id integer       
+) returns integer 
+as $$
+declare
+        v_item_id               cr_items.item_id%TYPE;
+        v_revision_id           cr_revisions.revision_id%TYPE;
+        v_id                    cr_items.item_id%TYPE;
+        v_task_number           integer;
+begin
+        select acs_object_id_seq.nextval into v_id from dual;
+
+        -- We want to put the task under the project item
+
+        -- create the task_number
+        
+        v_item_id := content_item__new (
+                v_id::varchar,          -- name
+                p_project_id,           -- parent_id
+                v_id,                   -- item_id
+                null,                   -- locale
+                now(),                  -- creation_date
+                p_creation_user,        -- creation_user
+                p_package_id,           -- context_id
+                p_creation_ip,          -- creation_ip
+                'content_item',         -- item_subtype
+                'pm_task',              -- content_type
+                p_title,                -- title
+                p_description,          -- description
+                'text/plain',           -- mime_type
+                null,                   -- nls_language
+                null                    -- data
+        );
+
+        v_revision_id := content_revision__new (
+                p_title,                -- title
+                p_description,          -- description
+                now(),                  -- publish_date
+                'text/plain',           -- mime_type
+                NULL,                   -- nls_language
+                NULL,                   -- data
+                v_item_id,              -- item_id
+                NULL,                   -- revision_id
+                now(),                  -- creation_date
+                p_creation_user,        -- creation_user
+                p_creation_ip           -- creation_ip
+        );
+
+        PERFORM content_item__set_live_revision (v_revision_id);
+
+        insert into pm_tasks (
+                task_id, task_number)
+        values (
+                v_item_id, v_task_number);
+
+        insert into pm_tasks_revisions (
+                task_revision_id, end_date, percent_complete, estimated_hours_work, estimated_hours_work_min, estimated_hours_work_max, actual_hours_worked)
+        values (
+                v_revision_id, p_end_date, p_percent_complete, p_estimated_hours_work, p_estimated_hours_work_min, p_estimated_hours_work_max, '0');
+
+        PERFORM acs_permission__grant_permission(
+                v_revision_id,
+                p_creation_user,
+                'admin'
+        );
+
+        return v_revision_id;
+end;
+$$ language plpgsql;
+
+
+select define_function_args('pm_task__new_task_revision', 'task_id, project_id, title, description, end_date, percent_complete, estimated_hours_work, estimated_hours_work_min, estimated_hours_work_max, actual_hours_worked, creation_date, creation_user, creation_ip, package_id');
+
+create function pm_task__new_task_revision (
+        p_task_id integer,     -- the item_id
+        p_project_id integer,
+        p_title varchar,
+        p_description varchar,
+        p_end_date timestamptz,
+        p_percent_complete numeric,
+        p_estimated_hours_work numeric,
+        p_estimated_hours_work_min numeric,
+        p_estimated_hours_work_max numeric,
+        p_actual_hours_worked numeric,
+        p_creation_date timestamptz,
+        p_creation_user integer,
+        p_creation_ip varchar,
+        p_package_id integer
+) returns integer 
+as $$
+declare
+        v_revision_id           cr_revisions.revision_id%TYPE;
+        v_id                    cr_items.item_id%TYPE;
+begin
+        select acs_object_id_seq.nextval into v_id from dual;
+
+        -- We want to put the task under the project item
+
+        v_revision_id := content_revision__new (
+                p_title,                -- title
+                p_description,          -- description
+                now(),                  -- publish_date
+                'text/plain',           -- mime_type
+                NULL,                   -- nls_language
+                NULL,                   -- data
+                p_task_id,              -- item_id
+                NULL,                   -- revision_id
+                now(),                  -- creation_date
+                p_creation_user,        -- creation_user
+                p_creation_ip           -- creation_ip
+        );
+
+        PERFORM content_item__set_live_revision (v_revision_id);
+
+        insert into pm_tasks_revisions (
+                task_revision_id, end_date, percent_complete, estimated_hours_work, estimated_hours_work_min, estimated_hours_work_max, actual_hours_worked)
+        values (
+                v_revision_id, p_end_date, p_percent_complete, p_estimated_hours_work, p_estimated_hours_work_min, p_estimated_hours_work_max, p_actual_hours_worked);
+
+        PERFORM acs_permission__grant_permission(
+                v_revision_id,
+                p_creation_user,
+                'admin'
+        );
+
+        return v_revision_id;
+end;
+$$ language plpgsql;
+
+
+-- The delete function deletes a record and all related overhead. 
+
+select define_function_args('pm_task__delete_task_item', 'task_id');
+
+create or replace function pm_task__delete_task_item (p_task_id integer)
+returns integer as $$
+declare
+begin
+        delete from pm_tasks_revisions
+                where task_revision_id in (select revision_id from pm_tasks_revisionsx where item_id = p_task_id);
+
+        delete from pm_tasks
+                where task_id = p_task_id;
+
+        raise NOTICE 'Deleting pm_task...';
+
+        PERFORM content_item__delete(p_task_id);
+        return 0;
+end;
+$$ language plpgsql;
+

Explanation of the columns in cr_items and cr_revisions

+cr_items: +
+item_id - unique id for this item, will be +different than the revision_id
parent_id - used to group items into a hierarchy (see +below)
name - this is used to make a URL by the content repository. +It must be unique per content folder. You can use a number, or +something like project_231. One way to do this is to set it equal +to a title plus the item_id.
locale - not sure, probably for internationalization +support
live_revision - this is equal to the cr_revision table's +revision_id that is the live version
latest_revision - this is equal to the cr_revision table's +revision_id that is the latest version
publish_status - not sure
content_type - not sure
storage_type - not sure, probably text or binary?
storage_area_key - not sure
tree_sortkey - a utility column used in hierarchical +queries.
+
+cr_revisions: +
+revision_id - a unique id for this revision.
item_id - a reference to the item_id for this revision
title - you can use this for your application. For example, +My Big Project
description - you can use this for your application, as a +longer description.
publish_date - the date this was published. Not sure if this +is for your use, or internal
mime_type - the mime type.
nls_language - I believe this is for +internationalization
lob - the binary content.
content - the text content.
content_length - the length of the text or binary +content?
+

Structuring your data into a hierarchy

+The content repository also has a very useful facility for +organizing your data into a hierarchy, very similar to a +file-system. Just like a file system, you can have folders to store +items inside of, and organize your information. The main difference +is that every item can also contain other items. So in our case, we +can have tasks that contain other tasks. This is a useful way for +us to specify sub-tasks, and sub-sub-tasks. In my case, building +project-management software, this also allows my tasks to be stored +underneath their given project. +

Using this structure is optional, but useful in many +circumstances.

The facility for this is built into the cr_items +data model. This makes sense, because you wouldn't want your +hierarchy associated with each revision. Here's how Postgres +describes the cr_items table:

+                         Table "public.cr_items"
+      Column      |          Type          |          Modifiers          
+------------------+------------------------+-----------------------------
+ item_id          | integer                | not null
+ parent_id        | integer                | not null
+ name             | character varying(400) | not null
+ locale           | character varying(4)   | 
+ live_revision    | integer                | 
+ latest_revision  | integer                | 
+ publish_status   | character varying(40)  | 
+ content_type     | character varying(100) | 
+ storage_type     | character varying(10)  | not null default 'text'
+ storage_area_key | character varying(100) | not null default 'CR_FILES'
+ tree_sortkey     | bit varying            | 
+
+The parent_id refers to either a content item +(cr_items), or a subclass of a content_item (such as +cr_folders). I'll explain more later about +cr_folders. +

One thing that you might want to do for your application is to +give the application its own root directory. Because the content +repository is shared among applications, this separates it off from +other applications. They can still use the items in your +application, but it must be a more deliberate process. If you don't +create your own root directory, you may see strange-looking data +from other applications in your application, or see your +application's data in other applications. There are times when +you'll want to do this, but probably not until you're much more +familiar with the content repository. Another reason for creating +your own root repository is that you application may be mounted +several times. If you want to separate the directory structure +between instances of your application, you need to create your own +root directory:

+-- Creates and returns a unique name for new project folders
+
+select define_function_args('pm_project__new_unique_name', 'package_id');
+
+create function pm_project__new_unique_name (p_package_id integer)
+returns text as $$
+declare
+        v_name                  cr_items.name%TYPE;
+        v_package_key           apm_packages.package_key%TYPE;
+        v_id                    integer;
+begin
+        select package_key into v_package_key from apm_packages
+            where package_id = p_package_id;
+
+        select acs_object_id_seq.nextval into v_id from dual;
+
+        -- Set the name
+        select v_package_key || '_' || 
+            to_char(current_timestamp, 'YYYYMMDD') || '_' ||
+            v_id into v_name;
+
+        return v_name;
+end;
+$$ language plpgsql;
+
+
+select define_function_args('pm_project__new_root_folder', 'package_id');
+
+create function pm_project__new_root_folder (p_package_id integer)
+returns integer as $$
+declare
+        v_folder_id                cr_folders.folder_id%TYPE;
+        v_folder_name           cr_items.name%TYPE;
+begin
+        -- Set the folder name
+        v_folder_name := pm_project__new_unique_name (p_package_id);
+
+        v_folder_id := content_folder__new (
+            v_folder_name,              -- name
+            'Projects',                 -- label
+            'Project Repository',       -- description
+            p_package_id                -- parent_id
+        );
+
+        -- Register the standard content types
+        PERFORM content_folder__register_content_type (
+            v_folder_id,         -- folder_id
+            'pm_project',        -- content_type
+            'f'                  -- include_subtypes
+        );
+
+        -- TODO: Handle Permissions here for this folder.
+
+        return v_folder_id;
+end;
+$$ language plpgsql;
+
+Note that this example is for projects rather than tasks. This is +because for the application I'm writing, projects are what tasks +are stored inside of. A project has many component tasks. If you +were writing another application, or if I wasn't doing anythign +with projects, then this would be creating a folder for just tasks. +

Typically, this definition would go in your +sql/postgresql/project-manager-create.sql file. If +this file is broken in several parts, this would go in the +project-manager-create-functions.sql portion.

Once you've created your root directory, you will set the +parent_id of your items to the id for the new root +repository (in our case, it's returned from the +pm_project__new_root_folder function)

In the project-manager application, we'll create a root +repository, and make all projects under that root repository. That +means they'll all have a parent_id set to the root +repository. However, we also want to make projects that are +sub-projects of other projects. In that case, we will set the +parent_id of the sub-project to the +item_id of the parent.

Understanding folders

+For a little while now, we have been talking about folders, but we +haven't delved into what CR folders are. Folders are sub-classes of +cr_items, and the only real difference is that they +contain no data, except for a label and description. +

If you create folders for your application, then you'll need to +make sure you manage them along with your other objects. For +example, if you were to add a folder for each of your objects, then +you would probably want to make sure you delete the folder when you +delete the object.

However, in many cases you are not creating more than one +folder. In fact, the only folder you might have will be the root +folder you create for each instance of your application (if you +install the project-manager in two parts of your web server, for +example, it should have two different root folders). When your +application is running, it can determine the root folder by +searching the cr_folders table. Here's the definition of that +table:

+                 Table "public.cr_folders"
+       Column       |          Type           |  Modifiers  
+--------------------+-------------------------+-------------
+ folder_id          | integer                 | not null
+ label              | character varying(1000) | 
+ description        | text                    | 
+ has_child_folders  | boolean                 | default 'f'
+ has_child_symlinks | boolean                 | default 'f'
+ package_id         | integer                 | 
+
+Note that there is a package_id column. The nice thing +about this column is that you can use it to find the root +repository, if you only have one folder per instance of your +application. You can get your package_id using this call within +your .tcl file: +
+set package_id [ad_conn package_id]
+
+Then you can find the root repository by using a query like this: +
+select folder_id from cr_folders where package_id = :package_id;
+

Create scripts

Drop scripts

+If you have problems with your drop script in OpenACS 4.6.2, then +Tammy's +drop scripts might be of interest to you. +

Using your data model

+You now have a shiny new data model that handles revisions and all +sorts of other things we haven't gotten to yet. Now, in your Tcl +pages and your ps/sql code, you can... + + + + + + +
Get latest revision (Tcl)set live_revision_id [db_exec_plsql get_live_revision "select +content_item__get_live_revision(:item_id)"]
Get latest revision (pl/sql)live_revision_id := +content_item__get_live_revision(:item_id);

The item_id identifies the content item with which the revision +is associated.

Likewise, the most recent revision of a content item can be +obtained with the content_item__get_latest_revision function

Reference:

Reference: Definitions

+
Content Type
A set of attributes that may be associated with a text or +binary content object. For example, a press_release content type +may include a title, byline, and publication date. These attributes +are stored in the cr_revisions table, and a table that +you set up to store specialized data. In this case, the title (I +think), byline, and publication date would be stored in a +specialized table.
+
+
Content Item
Items are the fundamental building blocks of the content +repository. Each item represents a distinct text or binary content +object that is publishable to the web, such as an article, report, +message or photograph. An item my also include any number of +attributes with more structured data, such as title, source, byline +and publication date.
+
+
Content Revision
A revision consists of the complete state of the item as it +existed at a certain point in time. This includes the main text or +binary object associated with the item, as well as all +attributes.
+
+
Content Folder
A folder is analogous to a folder or directory in a file +system. It represents a level in the content item hierarchy. In the +previous example, press-releases is a folder under the repository +root, and products is folder within that.
+
+
Symbolic Link
Analogous to a symlink, alias or shortcut in a file system. +Allows an item to be accessed from multiple folders.
+
+
Templates
Templates are merged with content items to render output in +HTML or other formats. Templates are assumed to be text files +containing static markup with embedded tags or code to incorporate +dynamic content in appropriate places.
+

Content templates

+The only place content templates are used in OpenACS are in the 5.0 +version of file storage. See CR and +content_template defined wrong

Troubleshooting

+One problem I ran into while trying to get my SQL create and drop +scripts working was that sometimes I wasn't able to delete a +content type because I would get errors like these: +
+Referential Integrity: attempting to delete live_revision: 658
+
+The problem seems to be that there were still items in the +cr_items table. You can remove them using select +content_item__delete(648); in psql. You get the codes by +doing a query like this: +
+select i.item_id, r.revision_id, r.title, i.content_type from cr_items i, cr_revisions r where i.item_id = r.item_id order by i.item_id, r.revision_id;
+
+Really, however, what you need to do is make sure your __delete and +drop scripts first go through and delete all children of those +items. I'm not sure if you need to delete the items themselves -- I +believe they may be dropped by themselves when the tables are +dropped, because of the cascade portion of the SQL +data model. +

When I was troubleshooting folders, I found this query +useful:

+select f.folder_id,f.label,f.description,i.content_type from cr_folders f, cr_items i where f.folder_id = i.item_id;
+

Once again, thanks to daveb for help in tracking this down (he +rocks!).

+ Index: openacs-4/packages/acs-content-repository/www/doc/uninstall.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/uninstall.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/uninstall.adp 16 Sep 2014 20:51:11 -0000 1.1.2.1 @@ -0,0 +1,27 @@ + +{/doc/acs-content-repository {Content Repository}} {Content Repository: Uninstalling} +Content Repository: Uninstalling + + + +

Uninstalling the Content Repository

Content Repository

The content repository includes an uninstall script, +sql/content-drop.sql. This script does two things:

    +
  1. Drops the attribute storage tables for all content types you +have defined.
  2. Drops the general tables for the content repository.
  3. +

The uninstall script does not do the following:

    +
  1. It does not delete rows from the acs_objects +table. Many other tables reference the object_id column in +this table, so there is the possibility that the uninstall script +will encounter foreign key reference errors.
  2. It does not delete types from the +acs_object_types table. As for objects themselves, it is +impossible for an automatic script to properly handle disposal of +all foreign key references.
  3. +

Because of what the uninstall script does not do, it is +only appropriate for removing the content repository in +preparation for removing the entire ACS Objects data model. If +you wish to upgrade an existing installation and cannot afford to +lose your data, you must run an upgrade script rather than +uninstalling the entire data model.


karlg@arsdigita.com
+Last revised: $Id: uninstall.html,v 1.1.1.1 2001/03/13 22:59:26 ben +Exp $ + Index: openacs-4/packages/acs-content-repository/www/doc/api/content.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/api/content.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/api/content.adp 16 Sep 2014 20:51:11 -0000 1.1.2.1 @@ -0,0 +1,58 @@ + +{/doc/acs-content-repository {Content Repository}} {Package: content} +Package: content + + + +

content

+Content Repository : content


  • Function content.blob_to_string
+ +
Parameters:
Not yet documented
Declaration:

+function blob_to_string(
+  blob_loc blob) return varchar2
+as language
+  java
+name
+  'com.arsdigita.content.Util.blobToString(
+    oracle.sql.BLOB
+   ) return java.lang.String';
+
+
  • Procedure content.blob_to_file
+ +
Parameters:
Not yet documented
Declaration:

+procedure blob_to_file(
+s varchar2, blob_loc blob)
+as language
+  java
+name
+  'com.arsdigita.content.Util.blobToFile(
+  java.lang.String, oracle.sql.BLOB
+  )';
+
+
  • Procedure content.string_to_blob
+ +
Parameters:
Not yet documented
Declaration:

+procedure string_to_blob(
+  s varchar2, blob_loc blob)
+as language
+  java
+name
+  'com.arsdigita.content.Util.stringToBlob(
+    java.lang.String, oracle.sql.BLOB
+   )';
+
+
  • Procedure content.string_to_blob_size
+ +
Parameters:
Not yet documented
Declaration:

+procedure string_to_blob_size(
+  s varchar2, blob_loc blob, blob_size number)
+as language
+  java
+name
+  'com.arsdigita.content.Util.stringToBlob(
+    java.lang.String, oracle.sql.BLOB, int
+   )';
+
+

Last Modified: $Id: content.html,v 1.1.1.1 2001/03/13 22:59:26 +ben Exp $

+ Index: openacs-4/packages/acs-content-repository/www/doc/api/extlink.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/api/extlink.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/api/extlink.adp 16 Sep 2014 20:51:11 -0000 1.1.2.1 @@ -0,0 +1,102 @@ + +{/doc/acs-content-repository {Content Repository}} {Package: content_extlink} +Package: content_extlink + + + +

content_extlink

+Content Repository : +content_extlink


 

Overview

External links are references to content pages on other web +sites. They provide the basis for maintaining a hierarchy of +"bookmarks" that may be managed in a manner analogous to other +content items. In particular, external links may be tagged with +keywords and related to the site's own content items.

 

Related Objects

+See also: {content_item } +

 

API

  • +Function: +content_extlink.is_extlink

Determines if the item is a extlink

+ + + + + + + +
Author:Karl Goldstein
Returns:'t' if the item is a extlink, 'f' otherwise
Parameters:
+ +
item_id:  The item id
Declaration:

+function is_extlink (
+  item_id          in cr_items.item_id%TYPE
+) return char;
+
+
See Also:content_extlink.new, content_extlink.resolve

 

  • +Function: content_extlink.new

Create a new extlink, an item pointing to an off-site +resource

+ + + + + + + +
Author:Karl Goldstein
Returns:The id of the newly created extlink
Parameters:
+ + + + + + + + + + + + + + + + + + + +
name:  The name for the new extlink, defaults to the name of the +target item
url:  The URL of the item
label:  The text label or title of the item
description:  A brief description of the item
parent_id:  The parent folder for the extlink. This must actually be a +folder and not a generic content item.
extlink_id:  The id of the new extlink. A new id will be allocated by +default
creation_date:  As in acs_object.new +
creation_ip:  As in acs_object.new +
creation_user:  As in acs_object.new +
Declaration:

+function new (
+  name          in cr_items.name%TYPE default null,
+  url           in cr_extlinks.url%TYPE,
+  label         in cr_extlinks.label%TYPE default null,
+  description   in cr_extlinks.description%TYPE default null,
+  parent_id     in acs_objects.context_id%TYPE,
+  extlink_id    in cr_extlinks.extlink_id%TYPE default null,
+  creation_date in acs_objects.creation_date%TYPE
+                           default sysdate,
+  creation_user in acs_objects.creation_user%TYPE
+                           default null,
+  creation_ip   in acs_objects.creation_ip%TYPE default null
+) return cr_extlinks.extlink_id%TYPE;
+
+
See Also:acs_object.new, content_item.new, content_extlink.resolve

 

  • +Procedure: content_extlink.delete

Deletes the extlink

+ + + + + +
Author:Karl Goldstein
Parameters:
+ +
extlink_id:  The id of the extlink to delete
Declaration:

+procedure delete (
+  extlink_id    in cr_extlinks.extlink_id%TYPE
+);
+
+
See Also:content_extlink.new, acs_object.delete

 

+Last Modified: $Id: extlink.html,v 1.1.1.1 2001/03/13 22:59:26 ben +Exp $ + Index: openacs-4/packages/acs-content-repository/www/doc/api/folder.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/api/folder.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/api/folder.adp 16 Sep 2014 20:51:12 -0000 1.1.2.1 @@ -0,0 +1,331 @@ + +{/doc/acs-content-repository {Content Repository}} {Package: content_folder} +Package: content_folder + + + +

content_folder

+Content Repository : +content_folder


 

Overview

Content folders contain related content items and allow content +managers to group content as they see fit. Within a content folder, +content items must have unique names since this is where they will +be served from. For example within the folder "movies" (served from +"/movies") all items must have unique names, such as: "terminator," +"terminator2" (served from "/movies/terminator, +"/movies/terminator2" respectively).

 

Related Objects

+See also: Content Item +

 

API

  • +Function: +content_folder.get_index_page

Returns the item ID of the index page of the folder, null +otherwise

+ + + + + +
Author:Michael Pih
Returns:The item ID of the index page
Parameters:
+ +
folder_id The:  folder id
Declaration:

+function get_index_page (
+  folder_id in cr_folders.folder_id%TYPE
+) return cr_items.item_id%TYPE;
+
+

 

  • +Function: content_folder.get_label

Returns the label for the folder. This function is the default +name method for the folder object.

+ + + + + + + +
Author:Karl Goldstein
Returns:The folder's label
Parameters:
+ +
folder_id:  The folder id
Declaration:

+function get_label (
+  folder_id in cr_folders.folder_id%TYPE
+) return cr_folders.label%TYPE;
+
+
See Also:acs_object_type.create_type, the docs for the name_method +parameter

 

  • +Function: content_folder.is_empty

Determine if the folder is empty

+ + + + + + + +
Author:Karl Goldstein
Returns:'t' if the folder contains no subfolders or items, +'f' otherwise
Parameters:
+ +
folder_id:  The folder id
Declaration:

+function is_empty (
+  folder_id  in cr_folders.folder_id%TYPE
+) return varchar2;
+
+
See Also:content_folder.is_folder

 

  • +Function: content_folder.is_folder

Determine if the item is a folder

+ + + + + + + +
Author:Karl Goldstein
Returns:'t' if the item is a folder, 'f' otherwise
Parameters:
+ +
item_id:  The item id
Declaration:

+function is_folder (
+  item_id         in cr_items.item_id%TYPE
+) return char;
+
+
See Also:content_folder.new, content_folder.is_sub_folder

 

  • +Function: +content_folder.is_registered

change this to is_type_registered Determines if a content type +is registered to the folder Only items of the registered type(s) +may be added to the folder.

+ + + + + + + +
Author:Karl Goldstein
Returns:'t' if the type is registered to this folder, 'f' +otherwise
Parameters:
+ + + + + + + +
folder_id:  The folder id
content_type:  The content type to be checked
include_subtypes:  If 't', all subtypes of the content_type will be +checked, returning 't' if all of them are registered. If 'f', only +an exact match with content_type will be performed.
Declaration:

+function is_registered (
+  folder_id             in cr_folders.folder_id%TYPE,
+  content_type          in cr_folder_type_map.content_type%TYPE,
+  include_subtypes      in varchar2 default 'f'
+) return varchar2;
+
+
See Also:content_folder.register_content_type, +content_folder.unregister_content_type,

 

  • +Function: +content_folder.is_sub_folder

Determine if the item target_folder_id is a subfolder +of the item folder_id +

+ + + + + + + +
Author:Karl Goldstein
Returns:'t' if the item target_folder_id is a +subfolder of the item folder_id, 'f' otherwise
Parameters:
+ + + + + +
folder_id:  The superfolder id
target_folder_id:  The subfolder id
Declaration:

+function is_sub_folder (
+  folder_id             in cr_folders.folder_id%TYPE,
+  target_folder_id      in cr_folders.folder_id%TYPE
+) return char;
+
+
See Also:content_folder.is_folder

 

  • +Function: content_folder.new

Create a new folder

+ + + + + + + +
Author:Karl Goldstein
Returns:The id of the newly created folder
Parameters:
+ + + + + + + + + + + + + + + + + +
label:  The label for the folder
description:  A short description of the folder, 4000 characters maximum
parent_id:  The parent of the folder
folder_id:  The id of the new folder. A new id will be allocated by +default
revision_id:  The id of the new revision. A new id will be allocated by +default
creation_date:  As in acs_object.new +
creation_ip:  As in acs_object.new +
creation_user:  As in acs_object.new +
Declaration:

+function new (
+  name          in cr_items.name%TYPE,
+  label         in cr_folders.label%TYPE,
+  description   in cr_folders.description%TYPE default null,
+  parent_id     in acs_objects.context_id%TYPE default null,
+  folder_id     in cr_folders.folder_id%TYPE default null,
+  creation_date in acs_objects.creation_date%TYPE
+                           default sysdate,
+  creation_user in acs_objects.creation_user%TYPE
+                           default null,
+  creation_ip   in acs_objects.creation_ip%TYPE default null
+) return cr_folders.folder_id%TYPE;
+
+
See Also:acs_object.new, content_item.new

 

  • +Procedure: content_folder.copy

Recursively copy the folder and all items in into a new +location. An error is thrown if either of the parameters is not a +folder. The root folder of the sitemap and the root folder of the +templates cannot be copied

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + +
folder_id:  The id of the folder to copy
target_folder_id:  The destination folder
Declaration:

+procedure copy (
+  folder_id             in cr_folders.folder_id%TYPE,
+  target_folder_id      in cr_folders.folder_id%TYPE
+);
+
+
See Also:content_folder.new, content_folder.copy

 

  • +Procedure: content_folder.delete

Delete a folder. An error is thrown if the folder is not +empty

+ + + + + +
Author:Karl Goldstein
Parameters:
+ +
folder_id:  The id of the folder to delete
Declaration:

+procedure delete (
+  folder_id     in cr_folders.folder_id%TYPE
+);
+
+
See Also:acs_object.delete, content_item.delete

 

  • +Procedure: content_folder.move

Recursively move the folder and all items in into a new +location. An error is thrown if either of the parameters is not a +folder. The root folder of the sitemap and the root folder of the +templates cannot be moved.

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + +
folder_id:  The id of the folder to move
target_folder_id:  The destination folder
Declaration:

+procedure move (
+  folder_id             in cr_folders.folder_id%TYPE,
+  target_folder_id      in cr_folders.folder_id%TYPE
+);
+
+
See Also:content_folder.new, content_folder.copy

 

  • +Procedure: +content_folder.register_content_type

Register a content type to the folder, if it is not already +registered. Only items of the registered type(s) may be added to +the folder.

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + +
folder_id:  The folder id
content_type:  The content type to be registered
Declaration:

+procedure register_content_type (
+  folder_id             in cr_folders.folder_id%TYPE,
+  content_type          in cr_folder_type_map.content_type%TYPE,
+  include_subtypes      in varchar2 default 'f'
+);
+
+
See Also:content_folder.unregister_content_type, +content_folder.is_registered

 

  • +Procedure: content_folder.edit_name

Change the name, label and/or description of the folder

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + + + + + +
folder_id:  The id of the folder to modify
name:  The new name for the folder. An error will be thrown if an item +with this name already exists under this folder's parent. If this +parameter is null, the old name will be preserved
label:  The new label for the folder. The old label will be preserved +if this parameter is null
label:  The new description for the folder. The old description will be +preserved if this parameter is null
Declaration:

+procedure rename (
+  folder_id      in cr_folders.folder_id%TYPE,
+  name           in cr_items.name%TYPE default null,
+  label          in cr_folders.label%TYPE default null,
+  description    in cr_folders.description%TYPE default null
+);
+
+
See Also:content_folder.new

 

  • +Procedure: +content_folder.unregister_content_type

Unregister a content type from the folder, if it has been +registered. Only items of the registered type(s) may be added to +the folder. If the folder already contains items of the type to be +unregistered, the items remain in the folder.

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + + + +
folder_id:  The folder id
content_type:  The content type to be unregistered
include_subtypes:  If 't', all subtypes of content_type will be +unregistered as well
Declaration:

+procedure unregister_content_type (
+  folder_id             in cr_folders.folder_id%TYPE,
+  content_type          in cr_folder_type_map.content_type%TYPE,
+  include_subtypes      in varchar2 default 'f'
+);
+
+
See Also:content_folder.register_content_type, +content_folder.is_registered

 

+Last Modified: $Id: folder.html,v 1.2 2004/06/01 22:54:18 donb Exp +$ + Index: openacs-4/packages/acs-content-repository/www/doc/api/item.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/api/item.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/api/item.adp 16 Sep 2014 20:51:12 -0000 1.1.2.1 @@ -0,0 +1,682 @@ + +{/doc/acs-content-repository {Content Repository}} {Package: content_item} +Package: content_item + + + +

content_item

+Content Repository : +content_item


 

Overview

Content items store the overview of the content published on a +website. The actual content is stored in content revisions. It is +implemented this way so that there can be mulitple versions of the +actual content while the main idea remains constant. For example: +If there is a review for the movie "Terminator," there will exist a +content item by the name "terminator" with all the right parameters +(supertype, parent, etc), there will also exist at least one +content revision pointing to this item with the actual review +content.

 

Related Objects

+See also: content_revision, content_folder +

 

API

  • +Function: +content_item.get_content_type

Retrieve the content type of this item. Only objects of this +type may be used as revisions for the item.

+ + + + + +
Author:Karl Goldstein
Returns:The content type of the item
Parameters:
+ +
item_id:  The item for which the content type is to be retrieved
Declaration:

+function get_content_type (
+  item_id     in cr_items.item_id%TYPE
+) return cr_items.content_type%TYPE;
+
+

 

  • +Function: content_item.get_context

Retrieve the parent of the given item

+ + + + + +
Author:Karl Goldstein
Returns:The id of the parent for this item
Parameters:
+ +
item_id:  The item for which the parent is to be retrieved
Declaration:

+function get_context (
+  item_id       in cr_items.item_id%TYPE
+) return acs_objects.context_id%TYPE;
+
+

 

  • +Function: content_item.get_id

Takes in a path, such as "/tv/programs/star_trek/episode_203" +and returns the id of the item with this path. Note: URLs are +abstract (no extensions are allowed in content item names and +extensions are stripped when looking up content items)

+ + + + + + + +
Author:Karl Goldstein
Returns:The id of the item with the given path, or null if +no such item exists
Parameters:
+ + + + + +
item_path:  The path to be resolved
root_folder_id:  Starts path resolution from this folder. Defaults to the root +of the sitemap
Declaration:

+function get_id (
+  item_path   in varchar2,
+  root_folder_id in cr_items.item_id%TYPE default c_root_folder_id
+) return cr_items.item_id%TYPE;
+
+
See Also:content_item.get_path

 

  • +Function: +content_item.get_latest_revision

Retrieves the id of the latest revision for the item (as opposed +to the live revision)

+ + + + + + + +
Author:Karl Goldstein
Returns:The id of the latest revision for this item, or +null if no revisions exist
Parameters:
+ +
item_id:  The item for which the latest revision is to be retrieved
Declaration:

+function get_latest_revision (
+  item_id    in cr_items.item_id%TYPE
+) return cr_revisions.revision_id%TYPE;
+
+
See Also:content_item.get_live_revision

 

  • +Function: +content_item.get_live_revision

Retrieves the id of the live revision for the item

Note that this function does nothing else besides retrieving the +value of the column cr_items.live_revision. It is thus +more efficient in many cases to join against cr_items +and retrieve the value directly.

+ + + + + +
Returns:The id of the live revision for this item, or null +if no live revision exists
Parameters:
+ +
item_id:  The item for which the live revision is to be retrieved
Declaration:

+function get_live_revision (
+  item_id   in cr_items.item_id%TYPE
+) return cr_revisions.revision_id%TYPE;
+
+
See Also:content_item.set_live_revision, +content_item.get_latest_revision

 

  • +Function: +content_item.get_parent_folder

Get the parent folder.

+ + + + + +
Author:Michael Pih
Returns:the folder_id of the parent folder, null +otherwise
Parameters:
+ +
item_id:  The item id
Declaration:

+function get_parent_folder (
+  item_id       in cr_items.item_id%TYPE
+) return cr_folders.folder_id%TYPE;
+
+

 

  • +Function: content_item.get_path

Retrieves the full path to an item, in the form of +"/tv/programs/star_trek/episode_203"

+ + + + + + + +
Author:Karl Goldstein
Returns:The path to the item
Parameters:
+ + + + + +
item_id:  The item for which the path is to be retrieved
root_folder_id:  Starts path resolution from this folder. Defaults to the root +of the sitemap
Declaration:

+function get_path (
+  item_id        in cr_items.item_id%TYPE,
+  root_folder_id in cr_items.item_id%TYPE default c_root_folder_id
+) return varchar2;
+
+
See Also:content_item.get_id, content_item.write_to_file

 

  • +Function: +content_item.get_publish_date

Retrieves the publish date for the item

+ + + + + + + +
Author:Karl Goldstein
Returns:The publish date for the item, or null if the item +has no revisions
Parameters:
+ + + + + +
item_id:  The item for which the publish date is to be retrieved
is_live:  If 't', use the live revision for the item. Otherwise, use the +latest revision. The default is 'f'
Declaration:

+function get_publish_date (
+  item_id    in cr_items.item_id%TYPE,
+  is_live    in char default 'f'
+) return cr_revisions.publish_date%TYPE;
+
+
See Also:content_item.get_live_revision, +content_item.get_latest_revision,

 

  • +Function: +content_item.get_revision_count

Return the total count of revisions for this item

+ + + + + + + +
Author:Karl Goldstein
Returns:The number of revisions for this item
Parameters:
+ +
item_id:  The id the item
Declaration:

+function get_revision_count (
+  item_id   in cr_items.item_id%TYPE
+) return number;
+
+
See Also:content_revision.new

 

  • +Function: +content_item.get_root_folder
+ +
Parameters:
Not yet documented
Declaration:

+function get_root_folder return cr_folders.folder_id%TYPE;
+
+

 

  • +Function: content_item.get_template

Retrieves the template which should be used to render this item. +If no template is registered to specifically render the item in the +given context, the default template for the item's type is +returned.

+ + + + + + + +
Author:Karl Goldstein
Returns:The id of the registered template, or null if no +template could be found
Parameters:
+ + + + + +
item_id:  The item for which the template will be unregistered
use_context:  The context in the item is to be rendered, such as 'admin' or +'public'
Declaration:

+function get_template (
+  item_id     in cr_items.item_id%TYPE,
+  use_context in cr_item_template_map.use_context%TYPE
+) return cr_templates.template_id%TYPE;
+
+
See Also:content_type.register_template, +content_item.register_template,

 

  • +Function: content_item.get_title

Retrieves the title for the item, using either the latest or the +live revision. If the specified item is in fact a folder, return +the folder's label. In addition, this function will automatically +resolve symlinks.

+ + + + + + + +
Author:Karl Goldstein
Returns:The title of the item
Parameters:
+ + + + + +
item_id:  The item for which the title is to be retrieved
is_live:  If 't', use the live revision to get the title. Otherwise, use +the latest revision. The default is 'f'
Declaration:

+function get_title (
+  item_id    in cr_items.item_id%TYPE,
+  is_live    in char default 'f'
+) return cr_revisions.title%TYPE;
+
+
See Also:content_item.get_live_revision, +content_item.get_latest_revision, content_symlink.resolve

 

  • +Function: +content_item.get_virtual_path

Retrieves the virtual path to an item, in the form of +"/tv/programs/star_trek/episode_203"

+ + + + + + + +
Author:Michael Pih
Returns:The virtual path to the item
Parameters:
+ + + + + +
item_id:  The item for which the path is to be retrieved
root_folder_id:  Starts path resolution from this folder. Defaults to the root +of the sitemap
Declaration:

+function get_virtual_path (
+  item_id        in cr_items.item_id%TYPE,
+  root_folder_id in cr_items.item_id%TYPE default c_root_folder_id
+) return varchar2;
+
+
See Also:content_item.get_id, content_item.write_to_file, +content_item.get_path

 

  • +Function: +content_item.is_index_page

Determine if the item is an index page for the specified folder. +The item is an index page for the folder if it exists in the folder +and its item name is "index".

+ + + + + + + +
Author:Karl Goldstein
Returns:'t' if the item is an index page for the specified +folder, 'f' otherwise
Parameters:
+ + + + + +
item_id:  The item id
folder_id:  The folder id
Declaration:

+function is_index_page (
+  item_id   in cr_items.item_id%TYPE,
+  folder_id in cr_folders.folder_id%TYPE
+) return varchar2;
+
+
See Also:content_folder.get_index_page

 

  • +Function: +content_item.is_publishable

Determines if an item is publishable. Publishable items must +meet the following criteria: 1) for each child type, the item has n +children, min_n < n < max_n 2) for each relation type, the +item has n relations, min_n < n < max_n 3) any +'publishing_wf' workflows are finished

+ + + + + +
Author:Michael Pih
Returns:'t' if the item is publishable in it's present +state, Otherwise, returns 'f'
Parameters:
+ +
item_id The:  item ID of the potential parent
Declaration:

+function is_publishable (
+  item_id               in cr_items.item_id%TYPE
+) return char;
+
+

 

  • +Function: content_item.is_subclass

Determines if one type is a subclass of another. A class is +always a subclass of itself.

+ + + + + + + +
Author:Karl Goldstein
Returns:'t' if the child class is a subclass of the +superclass, 'f' otherwise
Parameters:
+ + + + + +
object_type:  The child class
supertype:  The superclass
Declaration:

+function is_subclass (
+  object_type in acs_object_types.object_type%TYPE,
+  supertype     in acs_object_types.supertype%TYPE
+) return char;
+
+
See Also:acs_object_type.create_type

 

  • +Function: +content_item.is_valid_child

Determines if an item would be a valid child of another item by +checking if the parent allows children of the would-be child's +content type and if the parent already has n_max children of that +content type.

+ + + + + +
Author:Michael Pih
Returns:'t' if the item would be a valid child, 'f' +otherwise
Parameters:
+ + + + + +
item_id The:  item ID of the potential parent
content_type The:  content type of the potential child item
Declaration:

+function is_valid_child (
+  item_id       in cr_items.item_id%TYPE,
+  content_type  in acs_object_types.object_type%TYPE
+) return char;
+
+

 

  • +Function: content_item.new

Creates a new content item. If the data, title +or text parameters are specified, also creates a revision +for the item.

+ + + + + + + +
Author:Karl Goldstein
Returns:The id of the newly created item
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
name:  The name for the item, must be URL-encoded. If an item with +this name already exists under the specified parent item, an error +is thrown
parent_id:  The parent of this item, defaults to null
item_id:  The id of the new item. A new id will be allocated if this +parameter is null
locale:  The locale for this item, for use with Intermedia search
item_subtype:  The type of the new item, defaults to 'content_item' This +parameter is used to support inheritance, so that subclasses of +content_item can call this function to initialize the +parent class
content_type:  The content type for the item, defaults to 'content_revision'. +Only objects of this type may be used as revisions for the +item
title:  The user-readable title for the item, defaults to the item's +name
description:  A short description for the item (4000 characters maximum)
mime_type:  The file type of the item, defaults to 'text/plain'
nls_language:  The language for the item, used for Intermedia search
text:  The text content of the new revision, 4000 charcters maximum. +Cannot be specified simultaneously with the data +parameter
data:  The blob content of the new revison. Cannot be specified +simultaneously with the text parameter
relation_tag:  If a parent-child relationship is registered for these content +types, use this tag to describe the parent-child relationship. +Defaults to 'parent content type'-'child content type'
is_live:  If 't', the new revision will become live
creation_date:  As in acs_object.new +
creation_ip:  As in acs_object.new +
creation_user:  As in acs_object.new +
Declaration:

+function new (
+  name          in cr_items.name%TYPE,
+  parent_id     in acs_objects.context_id%TYPE default null,
+  item_id       in acs_objects.object_id%TYPE default null,
+  locale        in cr_items.locale%TYPE default null,
+  creation_date in acs_objects.creation_date%TYPE
+                           default sysdate,
+  creation_user in acs_objects.creation_user%TYPE
+                           default null,
+  creation_ip   in acs_objects.creation_ip%TYPE default null,
+  item_subtype  in acs_object_types.object_type%TYPE
+                           default 'content_item',
+  content_type  in acs_object_types.object_type%TYPE
+                           default 'content_revision',
+  title         in cr_revisions.title%TYPE default null,
+  description   in cr_revisions.description%TYPE default null,
+  mime_type     in cr_revisions.mime_type%TYPE default 'text/plain',
+  nls_language  in cr_revisions.nls_language%TYPE default null,
+  text          in varchar2 default null,
+  data          in cr_revisions.content%TYPE default null,
+  relation_tag  in cr_child_rels.relation_tag%TYPE default null,
+  is_live       in char default 'f'
+) return cr_items.item_id%TYPE;
+
+
See Also:acs_object.new

 

  • +Function: content_item.relate
+ +
Parameters:
Not yet documented
Declaration:

+function relate (
+  item_id       in cr_items.item_id%TYPE,
+  object_id     in acs_objects.object_id%TYPE,
+  relation_tag in cr_type_relations.relation_tag%TYPE default 'generic',
+  order_n       in cr_item_rels.order_n%TYPE default null,
+  relation_type in acs_object_types.object_type%TYPE default 'cr_item_rel'
+) return cr_item_rels.rel_id%TYPE;
+
+

 

  • +Procedure: content_item.copy

Copies the item to a new location, creating an identical item +with no revisions or associated workflow. If the target folder does +not exist, or if the folder already contains an item with the same +name as the given item, an error will be thrown.

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + +
item_id:  The item to be copied
target_folder_id:  The folder where the item is to be copied
Declaration:

+procedure copy (
+  item_id               in cr_items.item_id%TYPE,
+  target_folder_id      in cr_folders.folder_id%TYPE
+);
+
+
See Also:content_item.new, content_folder.new, content_item.move

 

  • +Procedure: content_item.delete

Deletes the specified content item, along with any revisions, +symlinks, workflows, and template relations for the item. Use with +caution - this operation cannot be undone.

+ + + + + +
Author:Karl Goldstein
Parameters:
+ +
item_id:  The id of the item to delete
Declaration:

+procedure delete (
+  item_id       in cr_items.item_id%TYPE
+);
+
+
See Also:acs_object.delete

 

  • +Procedure: content_item.move

Move the specified item to a different folder. If the target +folder does not exist, or if the folder already contains an item +with the same name as the given item, an error will be thrown.

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + +
item_id:  The item to be moved
target_folder_id:  The new folder for the item
Declaration:

+procedure move (
+  item_id               in cr_items.item_id%TYPE,
+  target_folder_id      in cr_folders.folder_id%TYPE
+);
+
+
See Also:content_item.new, content_folder.new, content_item.copy

 

  • +Procedure: +content_item.register_template

Registers a template which will be used to render this item.

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + + + +
item_id:  The item for which the template will be registered
template_id:  The template to be registered
use_context:  The context in which the template is appropriate, such as +'admin' or 'public'
Declaration:

+procedure register_template (
+  item_id      in cr_items.item_id%TYPE,
+  template_id  in cr_templates.template_id%TYPE,
+  use_context  in cr_item_template_map.use_context%TYPE
+);
+
+
See Also:content_type.register_template, +content_item.unregister_template, content_item.get_template

 

  • +Procedure: content_item.edit_name

Renames the item. If an item with the specified name already +exists under this item's parent, an error is thrown

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + +
item_id:  The id of the item to rename
name:  The new name for the item, must be URL-encoded
Declaration:

+procedure rename (
+  item_id        in cr_items.item_id%TYPE,
+  name           in cr_items.name%TYPE
+);
+
+
See Also:content_item.new

 

  • +Procedure: +content_item.set_live_revision

Make the specified revision the live revision for the item

+ + + + + +
Author:Karl Goldstein
Parameters:
+ +
revision_id:  The id of the revision which is to become live for its +corresponding item
Declaration:

+procedure set_live_revision (
+  revision_id   in cr_revisions.revision_id%TYPE,
+  publish_status in cr_items.publish_status%TYPE default 'ready'
+);
+
+
See Also:content_item.get_live_revision

 

  • +Procedure: +content_item.set_release_period

Sets the release period for the item. This information may be +used by applications to update the publishing status of items at +periodic intervals.

+ + + +
Author:Karl Goldstein
Parameters:
+ + + + + + + +
item_id:  The id the item.
start_when:  The time and date when the item should be released.
end_when:  The time and date when the item should be expired.
Declaration:

+procedure set_release_period (
+  item_id    in cr_items.item_id%TYPE,
+  start_when date default null,
+  end_when   date default null
+);
+
+

 

  • +Procedure: +content_item.unregister_template

Unregisters a template which will be used to render this +item.

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + + + +
item_id:  The item for which the template will be unregistered
template_id:  The template to be registered
use_context:  The context in which the template is appropriate, such as +'admin' or 'public'
Declaration:

+procedure unregister_template (
+  item_id      in cr_items.item_id%TYPE,
+  template_id  in cr_templates.template_id%TYPE default null,
+  use_context  in cr_item_template_map.use_context%TYPE default null
+);
+
+
See Also:content_type.register_template, content_item.register_template, +content_item.get_template

 

  • +Procedure: +content_item.unset_live_revision
+ +
Parameters:
Not yet documented
Declaration:

+procedure unset_live_revision (
+  --/** Set the live revision to null for the item
+  --    @author Michael Pih
+  --    @param item_id The id of the item for which to unset the live revision
+  --    @see {content_item.set_live_revision}
+  item_id      in cr_items.item_id%TYPE
+);
+
+

 

  • +Procedure: +content_item.write_to_file

Writes the content of the live revision of this item to a file, +creating all the neccessary directories in the process

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + +
item_id:  The item to be written to a file
root_path:  The path in the filesystem to which the root of the sitemap +corresponds
Declaration:

+procedure write_to_file (
+  item_id     in cr_items.item_id%TYPE,
+  root_path   in varchar2
+);
+
+
See Also:content_item.get_path

 

+Last Modified: $Id: item.adp,v 1.1.2.1 2014/09/16 20:51:12 gustafn Exp $ + Index: openacs-4/packages/acs-content-repository/www/doc/api/keyword.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/api/keyword.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/api/keyword.adp 16 Sep 2014 20:51:12 -0000 1.1.2.1 @@ -0,0 +1,285 @@ + +{/doc/acs-content-repository {Content Repository}} {Package: content_keyword} +Package: content_keyword + + + +

content_keyword

+Content Repository : +content_keyword


 

Overview

Keyword cassify a content_item. For example: If you have some +press releases about dogs. You might want assigning the Keyword dog +to every single content_item.

 

Related Objects

+See also: content_item +

 

API

  • +Function: +content_keyword.get_description

Retrieves the description of the content keyword

+ + + + + + + +
Author:Karl Goldstein
Returns:The description for the specified keyword
Parameters:
+ +
keyword_id:  The keyword id
Declaration:

+function get_description (
+  keyword_id  in cr_keywords.keyword_id%TYPE
+) return varchar2;
+
+
See Also:content_keyword.get_heading, +content_keyword.set_description

 

  • +Function: +content_keyword.get_heading

Retrieves the heading of the content keyword

+ + + + + + + +
Author:Karl Goldstein
Returns:The heading for the specified keyword
Parameters:
+ +
keyword_id:  The keyword id
Declaration:

+function get_heading (
+  keyword_id  in cr_keywords.keyword_id%TYPE
+) return varchar2;
+
+
See Also:content_keyword.set_heading, +content_keyword.get_description

 

  • +Function: content_keyword.get_path

Retreives a path to the keyword/subject category, with the most +general category at the root of the path

+ + + + + + + +
Author:Karl Goldstein
Returns:The path to the keyword, or null if no such +keyword exists
Parameters:
+ +
keyword_id:  The keyword id
Declaration:

+function get_path (
+  keyword_id in cr_keywords.keyword_id%TYPE
+) return varchar2;
+
+
See Also:content_keyword.new

 

  • +Function: +content_keyword.is_assigned

Determines if the keyword is assigned to the item

+ + + + + + + +
Author:Karl Goldstein
Returns:'t' if the keyword may be matched to an item, 'f' +otherwise
Parameters:
+ + + + + + + +
item_id:  The item id
keyword_id:  The keyword id to be checked for assignment
recurse:  Specifies if the keyword search is recursive. May be set to one +of the following values: +
    +
  • +none: Not recursive. Look for an exact match.
  • +up: Recursive from specific to general. A search for +"attack dogs" will also match "dogs", "animals", "mammals", +etc.
  • +down: Recursive from general to specific. A search for +"mammals" will also match "dogs", "attack dogs", "cats", "siamese +cats", etc.
  • +
+
Declaration:

+function is_assigned (
+  item_id      in cr_items.item_id%TYPE,
+  keyword_id   in cr_keywords.keyword_id%TYPE,
+  recurse      in varchar2 default 'none'
+) return varchar2;
+
+
See Also:content_keyword.item_assign

 

  • +Function: content_keyword.is_leaf

Determines if the keyword has no sub-keywords associated with +it

+ + + + + + + +
Author:Karl Goldstein
Returns:'t' if the keyword has no descendants, 'f' +otherwise
Parameters:
+ +
keyword_id:  The keyword id
Declaration:

+function is_leaf (
+  keyword_id  in cr_keywords.keyword_id%TYPE
+) return varchar2;
+
+
See Also:content_keyword.new

 

  • +Function: content_keyword.new

Creates a new keyword (also known as "subject category").

+ + + + + + + +
Author:Karl Goldstein
Returns:The id of the newly created keyword
Parameters:
+ + + + + + + + + + + + + + + + + +
heading:  The heading for the new keyword
description:  The description for the new keyword
parent_id:  The parent of this keyword, defaults to null.
keyword_id:  The id of the new keyword. A new id will be allocated if this +parameter is null
object_type:  The type for the new keyword, defaults to 'content_keyword'. +This parameter may be used by subclasses of +content_keyword to initialize the superclass.
creation_date:  As in acs_object.new +
creation_ip:  As in acs_object.new +
creation_user:  As in acs_object.new +
Declaration:

+function new (
+  heading       in cr_keywords.heading%TYPE,
+  description   in cr_keywords.description%TYPE default null,
+  parent_id     in cr_keywords.parent_id%TYPE default null,
+  keyword_id    in cr_keywords.keyword_id%TYPE default null,
+  creation_date in acs_objects.creation_date%TYPE
+                           default sysdate,
+  creation_user in acs_objects.creation_user%TYPE
+                           default null,
+  creation_ip   in acs_objects.creation_ip%TYPE default null,
+  object_type   in acs_object_types.object_type%TYPE default 'content_keyword'
+) return cr_keywords.keyword_id%TYPE;
+
+
See Also:acs_object.new, content_item.new, content_keyword.item_assign, +content_keyword.delete

 

  • +Procedure: content_keyword.delete

Deletes the specified keyword, which must be a leaf. Unassigns +the keyword from all content items. Use with caution - this +operation cannot be undone.

+ + + + + +
Author:Karl Goldstein
Parameters:
+ +
keyword_id:  The id of the keyword to be deleted
Declaration:

+procedure delete (
+  keyword_id  in cr_keywords.keyword_id%TYPE
+);
+
+
See Also:acs_object.delete, content_keyword.item_unassign

 

  • +Procedure: +content_keyword.item_assign

Assigns this keyword to a content item, creating a relationship +between them

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + + + + + + + +
item_id:  The item to be assigned to
keyword_id:  The keyword to be assigned
context_id:  As in acs_rel.new, deprecated
creation_ip:  As in acs_rel.new, deprecated
creation_user:  As in acs_rel.new, deprecated
Declaration:

+procedure item_assign (
+  item_id       in cr_items.item_id%TYPE,
+  keyword_id    in cr_keywords.keyword_id%TYPE,
+  context_id    in acs_objects.context_id%TYPE default null,
+  creation_user in acs_objects.creation_user%TYPE default null,
+  creation_ip   in acs_objects.creation_ip%TYPE default null
+);
+
+
See Also:acs_rel.new, content_keyword.item_unassign

 

  • +Procedure: +content_keyword.item_unassign

Unassigns this keyword to a content item, removing a +relationship between them

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + +
item_id:  The item to be unassigned from
keyword_id:  The keyword to be unassigned
Declaration:

+procedure item_unassign (
+  item_id     in cr_items.item_id%TYPE,
+  keyword_id  in cr_keywords.keyword_id%TYPE
+);
+
+
See Also:acs_rel.delete, content_keyword.item_assign

 

  • +Procedure: +content_keyword.set_description

Sets a new description for the keyword

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + +
keyword_id:  The keyword id
description:  The new description
Declaration:

+procedure set_description (
+  keyword_id  in cr_keywords.keyword_id%TYPE,
+  description in cr_keywords.description%TYPE
+);
+
+
See Also:content_keyword.set_heading, +content_keyword.get_description

 

  • +Procedure: +content_keyword.set_heading

Sets a new heading for the keyword

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + +
keyword_id:  The keyword id
heading:  The new heading
Declaration:

+procedure set_heading (
+  keyword_id  in cr_keywords.keyword_id%TYPE,
+  heading     in cr_keywords.heading%TYPE
+);
+
+
See Also:content_keyword.get_heading, +content_keyword.set_description

 

+Last Modified: $Id: keyword.html,v 1.1.1.1 2001/03/13 22:59:26 ben +Exp $ + Index: openacs-4/packages/acs-content-repository/www/doc/api/permission.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/api/permission.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/api/permission.adp 16 Sep 2014 20:51:12 -0000 1.1.2.1 @@ -0,0 +1,242 @@ + +{/doc/acs-content-repository {Content Repository}} {Package: content_permission} +Package: content_permission + + + +

content_permission

+Content Repository : +content_permission


 

Overview

Permissions can be set to allow certain users certain things. - +They can be compared with the Unix filesystem permission: read, +write ...

 

Related Objects

+See also: {content_item } +

 

API

  • +Function: +content_permission.has_grant_authority

Determine if the user may grant a certain permission to another +user. The permission may only be granted if the user has the +permission himself and posesses the cm_perm access, or if the user +posesses the cm_perm_admin access.

+ + + + + + + +
Author:Karl Goldstein
Returns:'t' if the donation is possible, 'f' +otherwise
Parameters:
+ + + + + + + +
object_id:  The object whose permissions are to be changed
holder_id:  The person who is attempting to grant the permissions
privilege:  The privilege to be granted
Declaration:

+  function has_grant_authority (
+    object_id         in acs_objects.object_id%TYPE,
+    holder_id         in parties.party_id%TYPE,
+    privilege         in acs_privileges.privilege%TYPE
+  ) return varchar2;
+
+
See Also:content_permission.grant_permission, +content_permission.is_has_revoke_authority, +acs_permission.grant_permission

 

  • +Function: +content_permission.has_revoke_authority

Determine if the user may take a certain permission away from +another user. The permission may only be revoked if the user has +the permission himself and posesses the cm_perm access, while the +other user does not, or if the user posesses the cm_perm_admin +access.

+ + + + + + + +
Author:Karl Goldstein
Returns:'t' if it is possible to revoke the privilege, 'f' +otherwise
Parameters:
+ + + + + + + + + +
object_id:  The object whose permissions are to be changed
holder_id:  The person who is attempting to revoke the permissions
privilege:  The privilege to be revoked
revokee_id:  The user from whom the privilege is to be taken away
Declaration:

+  function has_revoke_authority (
+    object_id         in acs_objects.object_id%TYPE,
+    holder_id         in parties.party_id%TYPE,
+    privilege         in acs_privileges.privilege%TYPE,
+    revokee_id        in parties.party_id%TYPE
+  ) return varchar2;
+
+
See Also:content_permission.has_grant_authority, +content_permission.revoke_permission, +acs_permission.revoke_permission

 

  • +Function: +content_permission.permission_p

Determine if the user has the specified permission on the +specified object. Does NOT check objects recursively: that is, if +the user has the permission on the parent object, he does not +automatically gain the permission on all the child objects.

+ + + + + + + +
Author:Karl Goldstein
Returns:'t' if the user has the specified permission on +the object, 'f' otherwise
Parameters:
+ + + + + + + +
object_id:  The object whose permissions are to be checked
holder_id:  The person whose permissions are to be examined
privilege:  The privilege to be checked
Declaration:

+  function permission_p (
+    object_id         in acs_objects.object_id%TYPE,
+    holder_id         in parties.party_id%TYPE,
+    privilege         in acs_privileges.privilege%TYPE
+  ) return varchar2;
+
+
See Also:content_permission.grant_permission, +content_permission.revoke_permission, +acs_permission.permission_p

 

  • +Procedure: +content_permission.grant_permission

This is a helper function for +content_permission.grant_permission and should not be called +individually.

Grants a permission and revokes all descendants of the +permission, since they are no longer relevant.

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + + + +
object_id:  The object whose permissions are to be changed
grantee_id:  The person who should gain the parent privilege
privilege:  The parent privilege to be granted
Declaration:

+  procedure grant_permission_h (
+    object_id         in acs_objects.object_id%TYPE,
+    grantee_id        in parties.party_id%TYPE,
+    privilege         in acs_privileges.privilege%TYPE
+  );
+
+
See Also:content_permission.grant_permission

 

  • +Procedure: +content_permission.grant_permission_h

This is a helper function for +content_permission.grant_permission and should not be called +individually.

Grants a permission and revokes all descendants of the +permission, since they are no longer relevant.

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + + + +
object_id:  The object whose permissions are to be changed
grantee_id:  The person who should gain the parent privilege
privilege:  The parent privilege to be granted
Declaration:

+  procedure grant_permission_h (
+    object_id         in acs_objects.object_id%TYPE,
+    grantee_id        in parties.party_id%TYPE,
+    privilege         in acs_privileges.privilege%TYPE
+  );
+
+
See Also:content_permission.grant_permission

 

  • +Procedure: +content_permission.inherit_permissions

Make the child object inherit all of the permissions of the +parent object. Typically, this function is called whenever a new +object is created under a given parent

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + +
parent_object_id:  The parent object id
child_object_id:  The child object id
Declaration:

+  procedure inherit_permissions (
+    parent_object_id  in acs_objects.object_id%TYPE,
+    child_object_id   in acs_objects.object_id%TYPE,
+    child_creator_id  in parties.party_id%TYPE default null
+  );
+
+
See Also:content_permission.grant, acs_permission.grant_permission

 

  • +Procedure: +content_permission.revoke_permission

This is a helper function for +content_permission.revoke_permission and should not be called +individually.

Revokes a permission but grants all child permissions to the +holder, to ensure that the permission is not permanently lost

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + + + +
object_id:  The object whose permissions are to be changed
revokee_id:  The person who should lose the parent permission
privilege:  The parent privilege to be revoked
Declaration:

+  procedure revoke_permission_h (
+    object_id         in acs_objects.object_id%TYPE,
+    revokee_id        in parties.party_id%TYPE,
+    privilege         in acs_privileges.privilege%TYPE
+  );
+
+
See Also:content_permission.revoke_permission

 

  • +Procedure: +content_permission.revoke_permission_h

This is a helper function for +content_permission.revoke_permission and should not be called +individually.

Revokes a permission but grants all child permissions to the +holder, to ensure that the permission is not permanently lost

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + + + +
object_id:  The object whose permissions are to be changed
revokee_id:  The person who should lose the parent permission
privilege:  The parent privilege to be revoked
Declaration:

+  procedure revoke_permission_h (
+    object_id         in acs_objects.object_id%TYPE,
+    revokee_id        in parties.party_id%TYPE,
+    privilege         in acs_privileges.privilege%TYPE
+  );
+
+
See Also:content_permission.revoke_permission

 

+Last Modified: $Id: permission.html,v 1.1.1.1 2001/03/13 22:59:26 +ben Exp $ + Index: openacs-4/packages/acs-content-repository/www/doc/api/revision.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/api/revision.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/api/revision.adp 16 Sep 2014 20:51:12 -0000 1.1.2.1 @@ -0,0 +1,218 @@ + +{/doc/acs-content-repository {Content Repository}} {Package: content_revision} +Package: content_revision + + + +

content_revision

+Content Repository : +content_revision


 

Overview

Content revisions contain the data for content items. There is a +many to one relationship between content revisions and content +items. There is at most one "live" revision for every content item +though. For example, there may be 5 revisions of the review for the +movie "Terminator," yet only one of these may be live on the +website at a given time.

 

Related Objects

+See also: {content_item } +

 

API

  • +Function: content_revision.copy

Creates a new copy of an attribute, including all attributes

+ + + + + +
Author:Karl Goldstein
Parameters:
+ +
revision_id:  The id of the revision to copy
Declaration:

+function copy (
+  revision_id   in cr_revisions.revision_id%TYPE,
+  copy_id       in cr_revisions.revision_id%TYPE default null
+) return cr_revisions.revision_id%TYPE;
+
+
See Also:content_revision.new

 

  • +Function: +content_revision.export_xml
+ +
Parameters:
Not yet documented
Declaration:

+function export_xml (
+  revision_id IN cr_revisions.revision_id%TYPE
+) return cr_xml_docs.doc_id%TYPE;
+
+

 

  • +Function: +content_revision.get_number

Return the revision number of the specified revision, according +to the chronological order in which revisions have been added for +this item.

+ + + + + + + +
Author:Karl Goldstein
Returns:The number of the revision
Parameters:
+ +
revision_id:  The id the revision
Declaration:

+function get_number (
+  revision_id   in cr_revisions.revision_id%TYPE
+) return number;
+
+
See Also:content_revision.new

 

  • +Function: +content_revision.import_xml
+ +
Parameters:
Not yet documented
Declaration:

+function import_xml (
+  item_id IN cr_items.item_id%TYPE,
+  revision_id IN cr_revisions.revision_id%TYPE,
+  doc_id IN number
+) return cr_revisions.revision_id%TYPE;
+
+

 

  • +Function: content_revision.new

Create a new revision for an item.

+ + + + + + + +
Author:Karl Goldstein
Returns:The id of the newly created revision
Parameters:
+ + + + + + + + + + + + + + + + + + + + + + + +
title:  The revised title for the item
description:  A short description of this revision, 4000 characters +maximum
publish_date:  Publication date.
mime_type:  The revised mime type of the item, defaults to +'text/plain'
nls_language:  The revised language of the item, for use with Intermedia +searching
data:  The blob which contains the body of the revision
item_id:  The id of the item being revised
revision_id:  The id of the new revision. A new id will be allocated by +default
creation_date:  As in acs_object.new +
creation_ip:  As in acs_object.new +
creation_user:  As in acs_object.new +
Declaration:

+function new (
+  title         in cr_revisions.title%TYPE,
+  description   in cr_revisions.description%TYPE default null,
+  publish_date  in cr_revisions.publish_date%TYPE default sysdate,
+  mime_type     in cr_revisions.mime_type%TYPE default 'text/plain',
+  nls_language  in cr_revisions.nls_language%TYPE default null,
+  data          in cr_revisions.content%TYPE,
+  item_id       in cr_items.item_id%TYPE,
+  revision_id   in cr_revisions.revision_id%TYPE default null,
+  creation_date in acs_objects.creation_date%TYPE
+                           default sysdate,
+  creation_user in acs_objects.creation_user%TYPE
+                           default null,
+  creation_ip   in acs_objects.creation_ip%TYPE default null
+) return cr_revisions.revision_id%TYPE;
+
+
See Also:acs_object.new, content_item.new

 

  • +Function: content_revision.read_xml
+ +
Parameters:
Not yet documented
Declaration:

+function read_xml (
+  item_id IN number,
+  revision_id IN number,
+  clob_loc IN clob
+) return number as language
+  java
+name
+  'com.arsdigita.content.XMLExchange.importRevision(
+     java.lang.Integer, java.lang.Integer, oracle.sql.CLOB
+  ) return int';
+
+

 

  • +Function: +content_revision.write_xml
+ +
Parameters:
Not yet documented
Declaration:

+function write_xml (
+  revision_id IN number,
+  clob_loc IN clob
+) return number as language
+  java
+name
+  'com.arsdigita.content.XMLExchange.exportRevision(
+     java.lang.Integer, oracle.sql.CLOB
+  ) return int';
+
+

 

  • +Procedure: content_revision.delete

Deletes the revision.

+ + + + + +
Author:Karl Goldstein
Parameters:
+ +
revision_id:  The id of the revision to delete
Declaration:

+procedure delete (
+  revision_id   in cr_revisions.revision_id%TYPE
+);
+
+
See Also:content_revision.new, acs_object.delete

 

  • +Procedure: +content_revision.index_attributes

Generates an XML document for insertion into +cr_revision_attributes, which is indexed by Intermedia for +searching attributes.

+ + + + + +
Author:Karl Goldstein
Parameters:
+ +
revision_id:  The id of the revision to index
Declaration:

+procedure index_attributes(
+  revision_id IN cr_revisions.revision_id%TYPE
+);
+
+
See Also:content_revision.new

 

  • +Procedure: content_revision.replace
+ +
Parameters:
Not yet documented
Declaration:

+procedure replace(
+  revision_id number, search varchar2, replace varchar2)
+as language
+  java
+name
+  'com.arsdigita.content.Regexp.replace(
+    int, java.lang.String, java.lang.String
+   )';
+
+

 

  • +Procedure: content_revision.to_html

Converts a revision uploaded as a binary document to html

+ + + +
Author:Karl Goldstein
Parameters:
+ +
revision_id:  The id of the revision to index
Declaration:

+procedure to_html (
+  revision_id IN cr_revisions.revision_id%TYPE
+);
+
+

 

+Last Modified: $Id: revision.html,v 1.1.1.1 2001/03/13 22:59:26 ben +Exp $ + Index: openacs-4/packages/acs-content-repository/www/doc/api/symlink.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/api/symlink.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/api/symlink.adp 16 Sep 2014 20:51:12 -0000 1.1.2.1 @@ -0,0 +1,151 @@ + +{/doc/acs-content-repository {Content Repository}} {Package: content_symlink} +Package: content_symlink + + + +

content_symlink

+Content Repository : +content_symlink


 

Overview

Symlinks are pointers to items within the content repository. +They are simply used to create links between content items.

 

Related Objects

+See also: content_item, content_folder +

 

API

  • +Function: +content_symlink.is_symlink

Determines if the item is a symlink

+ + + + + + + +
Author:Karl Goldstein
Returns:'t' if the item is a symlink, 'f' otherwise
Parameters:
+ +
item_id:  The item id
Declaration:

+function is_symlink (
+  item_id          in cr_items.item_id%TYPE
+) return char;
+
+
See Also:content_symlink.new, content_symlink.resolve

 

  • +Function: content_symlink.new

Create a new symlink, linking two items

+ + + + + + + +
Author:Karl Goldstein
Returns:The id of the newly created symlink
Parameters:
+ + + + + + + + + + + + + + + + + +
name:  The name for the new symlink, defaults to the name of the +target item
label :  The label of the symlink, defaults to 'Symlink to +<target_item_name>'
target_id:  The item which the symlink will point to
parent_id:  The parent folder for the symlink. This must actually be a +folder and not a generic content item.
symlink_id:  The id of the new symlink. A new id will be allocated by +default
creation_date:  As in acs_object.new +
creation_ip:  As in acs_object.new +
creation_user:  As in acs_object.new +
Declaration:

+function new (
+  name          in cr_items.name%TYPE default null,
+  label         in cr_symlinks.label%TYPE default null,
+  target_id     in cr_items.item_id%TYPE,
+  parent_id     in acs_objects.context_id%TYPE,
+  symlink_id    in cr_symlinks.symlink_id%TYPE default null,
+  creation_date in acs_objects.creation_date%TYPE
+                           default sysdate,
+  creation_user in acs_objects.creation_user%TYPE
+                           default null,
+  creation_ip   in acs_objects.creation_ip%TYPE default null
+) return cr_symlinks.symlink_id%TYPE;
+
+
See Also:acs_object.new, content_item.new, content_symlink.resolve

 

  • +Function: content_symlink.resolve

Resolves the symlink and returns the target item id.

+ + + + + + + +
Author:Karl Goldstein
Returns:The target item of the symlink, or the original +item id if the item is not in fact a symlink
Parameters:
+ +
item_id:  The item id to be resolved
Declaration:

+function resolve (
+  item_id       in cr_items.item_id%TYPE
+) return cr_items.item_id%TYPE;
+
+
See Also:content_symlink.new, content_symlink.is_symlink

 

  • +Function: +content_symlink.resolve_content_type

Gets the content type of the target item.

+ + + + + + + +
Author:Michael Pih
Returns:The content type of the symlink target, otherwise +null. the item is not in fact a symlink
Parameters:
+ +
item_id:  The item id to be resolved
Declaration:

+function resolve_content_type (
+  item_id       in cr_items.item_id%TYPE
+) return cr_items.content_type%TYPE;
+
+
See Also:content_symlink.resolve

 

  • +Procedure: content_symlink.copy

Copies the symlink itself to another folder, without resolving +the symlink

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + +
symlink_id:  The id of the symlink to copy
target_folder_id:  The id of the folder where the symlink is to be copied
Declaration:

+procedure copy (
+  symlink_id            in cr_symlinks.symlink_id%TYPE,
+  target_folder_id      in cr_folders.folder_id%TYPE
+);
+
+
See Also:content_symlink.new, content_item.copy

 

  • +Procedure: content_symlink.delete

Deletes the symlink

+ + + + + +
Author:Karl Goldstein
Parameters:
+ +
symlink_id:  The id of the symlink to delete
Declaration:

+procedure delete (
+  symlink_id    in cr_symlinks.symlink_id%TYPE
+);
+
+
See Also:content_symlink.new, acs_object.delete

 

+Last Modified: $Id: symlink.html,v 1.1.1.1.28.1 2014/09/16 20:43:09 +gustafn Exp $ + Index: openacs-4/packages/acs-content-repository/www/doc/api/template.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/api/template.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/api/template.adp 16 Sep 2014 20:51:12 -0000 1.1.2.1 @@ -0,0 +1,128 @@ + +{/doc/acs-content-repository {Content Repository}} {Package: content_template} +Package: content_template + + + +

content_template

+Content Repository : +content_template


 

Overview

Templates are a special class of text objects that are used for +specifying the layout of a content item. They may be mapped to +content types, meaning that every item of that type will display +using that template unless a specific item overrides the default by +mapping to a template itself.

 

Related Objects

+See also: content_item, content_folder +

 

API

  • +Function: content_template.get_path

Retrieves the full path to the template, as described in +content_item.get_path

+ + + + + + + +
Author:Karl Goldstein
Returns:The path to the template, starting with the +specified root folder
Parameters:
+ + + + + +
template_id:  The id of the template for which the path is to be +retrieved
root_folder_id:  Starts path resolution at this folder
Declaration:

+function get_path (
+  template_id    in cr_templates.template_id%TYPE,
+  root_folder_id in cr_folders.folder_id%TYPE default c_root_folder_id
+) return varchar2;
+
+
See Also:content_item.get_path

 

  • +Function: +content_template.get_root_folder
+ +
Parameters:
Not yet documented
Declaration:

+function get_root_folder return cr_folders.folder_id%TYPE;
+
+

 

  • +Function: +content_template.is_template

Determine if an item is a template.

+ + + + + + + +
Author:Karl Goldstein
Returns:'t' if the item is a template, 'f' otherwise
Parameters:
+ +
item_id:  The item id
Declaration:

+function is_template (
+  template_id   in cr_templates.template_id%TYPE
+) return varchar2;
+
+
See Also:content_template.new

 

  • +Function: content_template.new

Creates a new content template which can be used to render +content items.

+ + + + + + + +
Author:Karl Goldstein
Returns:The id of the newly created template
Parameters:
+ + + + + + + + + + + + + +
name:  The name for the template, must be a valid UNIX-like filename. +If a template with this name already exists under the specified +parent item, an error is thrown
parent_id:  The parent of this item, defaults to null
template_id:  The id of the new template. A new id will be allocated if this +parameter is null
creation_date:  As in acs_object.new +
creation_ip:  As in acs_object.new +
creation_user:  As in acs_object.new +
Declaration:

+function new (
+  name          in cr_items.name%TYPE,
+  parent_id     in acs_objects.context_id%TYPE default null,
+  template_id   in cr_templates.template_id%TYPE default null,
+  creation_date in acs_objects.creation_date%TYPE
+                           default sysdate,
+  creation_user in acs_objects.creation_user%TYPE
+                           default null,
+  creation_ip   in acs_objects.creation_ip%TYPE default null
+) return cr_templates.template_id%TYPE;
+
+
See Also:acs_object.new, content_item.new, +content_item.register_template, content_type.register_template

 

  • +Procedure: content_template.delete

Deletes the specified template, and unregisters the template +from all content types and content items. Use with caution - this +operation cannot be undone.

+ + + + + +
Author:Karl Goldstein
Parameters:
+ +
template_id:  The id of the template to delete
Declaration:

+procedure delete (
+  template_id   in cr_templates.template_id%TYPE
+);
+
+
See Also:acs_object.delete, content_item.unregister_template, +content_type.unregister_template,

 

+Last Modified: $Id: template.html,v 1.1.1.1 2001/03/13 22:59:26 ben +Exp $ + Index: openacs-4/packages/acs-content-repository/www/doc/api/type.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/api/type.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/api/type.adp 16 Sep 2014 20:51:13 -0000 1.1.2.1 @@ -0,0 +1,406 @@ + +{/doc/acs-content-repository {Content Repository}} {Package: content_type} +Package: content_type + + + +

content_type

+Content Repository : +content_type


 

Overview

This package is used to manipulate content types and attributes +Content types represent the different kind of content displayed on +a website. All content items should subclass a content type.

 

Related Objects

+See also: {Content Item } +

 

API

  • +Function: +content_type.create_attribute

Create a new attribute for the specified type. Automatically +create the column for the attribute if the column does not already +exist.

+ + + + + + + +
Author:Karl Goldstein
Returns:The id of the newly created attribute
Parameters:
+ + + + + + + + + + + +
content_type:  The name of the type to alter
attribute_name:  The name of the attribute to create
pretty_name:  Pretty name for the new attribute, singular
pretty_plural:  Pretty name for the new attribute, plural
default_value:  The default value for the attribute, defaults to null
Declaration:

+function create_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,
+  default_value in acs_attributes.default_value%TYPE default null,
+  column_spec           in varchar2  default 'varchar2(4000)'
+) return acs_attributes.attribute_id%TYPE;
+
+
See Also:acs_object_type.create_attribute, content_type.create_type

 

  • +Function: content_type.get_template

Retrieve the appropriate template for rendering items of the +specified type.

+ + + + + + + +
Author:Karl Goldstein
Returns:The ID of the template to use
Parameters:
+ + + + + +
content_type:  The type for which the template is to be retrieved
use_context:  The context in which the template is appropriate, such as +'admin' or 'public'
Declaration:

+function get_template (
+  content_type  in cr_type_template_map.content_type%TYPE,
+  use_context   in cr_type_template_map.use_context%TYPE
+) return cr_templates.template_id%TYPE;
+
+
See Also:content_item.register_template, +content_item.unregister_template, content_item.get_template, +content_type.unregister_template, content_type.register_template, +content_type.set_default_template

 

  • +Function: +content_type.is_content_type
+ +
Parameters:
Not yet documented
Declaration:

+function is_content_type (
+  object_type   in acs_object_types.object_type%TYPE
+) return char;
+
+

 

  • +Procedure: content_type.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
Parameters:
+ + + + + + + + + + + + + + + +
content_type:  The name of the new type
supertype:  The supertype, defaults to content_revision
pretty_name:  Pretty name for the type, singular
pretty_plural:  Pretty name for the type, plural
table_name:  The name for the attribute table, defaults to the name of the +supertype
id_column:  The primary key for the table, defaults to 'XXX'
name_method:  As in acs_object_type.create_type +
Declaration:

+procedure 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 default null,
+  id_column             in acs_object_types.id_column%TYPE default 'XXX',
+  name_method           in acs_object_types.name_method%TYPE default null
+);
+
+
See Also:acs_object_type.create_type

 

  • +Procedure: +content_type.drop_attribute

Drop an existing attribute. If you are using CMS, make sure to +call cm_form_widget.unregister_attribute_widget before +calling this function.

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + + + +
content_type:  The name of the type to alter
attribute_name:  The name of the attribute to drop
drop_column:  If 't', will also alter the table and remove the column where +the attribute is stored. The default is 'f' (leaves the table +untouched).
Declaration:

+procedure drop_attribute (
+  content_type          in acs_attributes.object_type%TYPE,
+  attribute_name        in acs_attributes.attribute_name%TYPE,
+  drop_column           in varchar2 default 'f'
+);
+
+
See Also:acs_object.drop_attribute, content_type.create_attribute, +cm_form_widget.unregister_attribute_widget

 

  • +Procedure: +content_type.refresh_view

Create a view for the type which joins all attributes of the +type, including the inherited attributes. The view is named "

+X" Called by create_attribute and create_type. + + + + + + +
Author:Karl Goldstein
Parameters:
+ +
content_type:  The type for which the view is to be created.
Declaration:

+procedure refresh_view (
+  content_type  in cr_type_template_map.content_type%TYPE
+);
+
+
See Also:content_type.create_type

 

  • +Procedure: +content_type.register_child_type

Register a parent-child relationship between a content type and +another object type. This may then be used by the +content_item.is_valid_relation function to validate the +relationship between an item and a potential child.

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + + + + + + + +
content_type:  The type of the item from which the relationship +originated.
child_type:  The type of the child item.
relation_tag:  A simple token used to identify a set of relations.
min_n:  The minimun number of parent-child relationships of this type +which an item must have to go live.
max_n:  The minimun number of relationships of this type which an item +must have to go live.
Declaration:

+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
+);
+
+
See Also:content_type.register_relation_type, +content_type.register_child_type

 

  • +Procedure: +content_type.register_mime_type
+ +
Parameters:
Not yet documented
Declaration:

+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
+);
+
+

 

  • +Procedure: +content_type.register_relation_type

Register a relationship between a content type and another +object type. This may then be used by the +content_item.is_valid_relation function to validate any +relationship between an item and another object.

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + + + + + + + +
content_type:  The type of the item from which the relationship +originated.
target_type:  The type of the item to which the relationship is +targeted.
relation_tag:  A simple token used to identify a set of relations.
min_n:  The minimun number of relationships of this type which an item +must have to go live.
max_n:  The minimun number of relationships of this type which an item +must have to go live.
Declaration:

+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
+);
+
+
See Also:content_type.unregister_relation_type

 

  • +Procedure: +content_type.register_template

Register a template for the content type. This template may be +used to render all items of that type.

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + + + + + +
content_type:  The type for which the template is to be registered
template_id:  The ID of the template to register
use_context:  The context in which the template is appropriate, such as +'admin' or 'public'
is_default:  If 't', this template becomes the default template for the +type, default is 'f'.
Declaration:

+procedure register_template (
+  content_type  in cr_type_template_map.content_type%TYPE,
+  template_id   in cr_templates.template_id%TYPE,
+  use_context   in cr_type_template_map.use_context%TYPE,
+  is_default    in cr_type_template_map.is_default%TYPE default 'f'
+);
+
+
See Also:content_item.register_template, +content_item.unregister_template, content_item.get_template, +content_type.unregister_template, +content_type.set_default_template, content_type.get_template

 

  • +Procedure: +content_type.set_default_template

Make the registered template a default template. The default +template will be used to render all items of the type for which no +individual template is registered.

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + + + +
content_type:  The type for which the template is to be made default
template_id:  The ID of the template to make default
use_context:  The context in which the template is appropriate, such as +'admin' or 'public'
Declaration:

+procedure set_default_template (
+  content_type  in cr_type_template_map.content_type%TYPE,
+  template_id   in cr_templates.template_id%TYPE,
+  use_context   in cr_type_template_map.use_context%TYPE
+);
+
+
See Also:content_item.register_template, +content_item.unregister_template, content_item.get_template, +content_type.unregister_template, content_type.register_template, +content_type.get_template

 

  • +Procedure: +content_type.unregister_child_type

Register a parent-child relationship between a content type and +another object type. This may then be used by the +content_item.is_valid_relation function to validate the +relationship between an item and a potential child.

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + + + +
parent_type:  The type of the parent item.
child_type:  The type of the child item.
relation_tag:  A simple token used to identify a set of relations.
Declaration:

+procedure unregister_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 null
+);
+
+
See Also:content_type.register_relation_type, +content_type.register_child_type

 

  • +Procedure: +content_type.unregister_mime_type
+ +
Parameters:
Not yet documented
Declaration:

+procedure unregister_mime_type (
+  content_type  in cr_content_mime_type_map.content_type%TYPE,
+  mime_type     in cr_content_mime_type_map.mime_type%TYPE
+);
+
+

 

  • +Procedure: +content_type.unregister_relation_type

Unregister a relationship between a content type and another +object type.

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + + + +
content_type:  The type of the item from which the relationship +originated.
target_type:  The type of the item to which the relationship is +targeted.
relation_tag:  A simple token used to identify a set of relations.
Declaration:

+procedure unregister_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 null
+);
+
+
See Also:content_type.register_relation_type

 

  • +Procedure: +content_type.unregister_template

Unregister a template. If the unregistered template was the +default template, the content_type can no longer be rendered in the +use_context,

+ + + + + +
Author:Karl Goldstein
Parameters:
+ + + + + + + +
content_type:  The type for which the template is to be unregistered
template_id:  The ID of the template to unregister
use_context:  The context in which the template is to be unregistered
Declaration:

+procedure unregister_template (
+  content_type  in cr_type_template_map.content_type%TYPE default null,
+  template_id   in cr_templates.template_id%TYPE,
+  use_context   in cr_type_template_map.use_context%TYPE default null
+);
+
+
See Also:content_item.register_template, +content_item.unregister_template, content_item.get_template, +content_type.set_default_template, content_type.register_template, +content_type.get_template

 

+Last Modified: $Id: type.html,v 1.1.1.1 2001/03/13 22:59:26 ben Exp +$ + Index: openacs-4/packages/acs-content-repository/www/doc/guide/access-control.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/guide/access-control.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/guide/access-control.adp 16 Sep 2014 20:51:13 -0000 1.1.2.1 @@ -0,0 +1,7 @@ + +{/doc/acs-content-repository {Content Repository}} {} + + + +

Last Modified: $Id: access-control.html,v 1.1.1.1 2001/03/13 +22:59:26 ben Exp $

Index: openacs-4/packages/acs-content-repository/www/doc/guide/convert.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/guide/convert.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/guide/convert.adp 16 Sep 2014 20:51:13 -0000 1.1.2.1 @@ -0,0 +1,42 @@ + +{/doc/acs-content-repository {Content Repository}} {Content Repository Developer Guide: HTML Conversion} +Content Repository Developer Guide: HTML Conversion + + + +

Converting Binary Documents to HTML

+Content Repository : Developer +Guide

The content repository uses the INSO libraries included with +Intermedia to support conversion of binary files such as Microsoft +Word documents to HTML. This document describes how to make this +conversion be part of the item creation or editing process, such +that the content is always stored in the repository as HTML.

+Note: Because temporary tables and LOB storage are used +during the conversion process, the entire process described here +must be performed within the context of a single transaction.

Create the Revision

The first step is to create the revision that will be associated +with the converted document, and obtain the corresponding ID. The +content column for the revision must be initialized with +an empty blob object:

+revision_id := content_revision.new(item_id => :item_id,
+                                    revision_id => :revision_id,
+                                    data => empty_blob(),
+                                    title => 'My Word Document',
+                                    ...);
+

Uploading Binary Files

The next step in the process is to upload the binary file into +the temporary table cr_doc_filter. This may be done using +any standard technique for uploading a binary file, such as an +image. The temporary table has only two columns; one is a BLOB to +store the document itself, and one is the revision ID.

Converting the Document

Once the revision has been created and the file has been +uploaded, the file may be converted to HTML and written into the +empty blob associated with the revision. This is done with the +to_html procedure in the content_revision +package:

+begin
+  content_revision.to_html(:revision_id);
+end;
+/
+

Once the transaction is committed, the uploaded document is +automatically deleted from the cr_doc_filter table.


karlg@arsdigita.com
+Last Modified: $Id: convert.html,v 1.1.1.1 2001/03/13 22:59:26 ben +Exp $ + Index: openacs-4/packages/acs-content-repository/www/doc/guide/file-system.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/guide/file-system.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/guide/file-system.adp 16 Sep 2014 20:51:13 -0000 1.1.2.1 @@ -0,0 +1,94 @@ + +{/doc/acs-content-repository {Content Repository}} {Content Repository Developer Guide: Organizing Content +Items} +Content Repository Developer Guide: Organizing Content +Items + + + +

Organizing Content Items

+ACS Documentation : Content Repository : Developer Guide

The content repository organizes content items in a hierarchical +structure similar to a file system. You manage content items in the +repository using the same basic operations as in a file system:

    +
  • A freshly installed content repository consists of a single +"root" folder (analogous to the root directory / in UNIX +or an empty partition in Windows or MacOS).
  • You organize items by creating subfolders under the root.
  • You can move or copy items from one folder to another.
  • You can create "links" or "shortcuts" for items to make them +accessible from within other directories.
  • Each item has a "file name" and an absolute "path" that is +determined by its location on a particular branch of the repository +tree. For example, the path to an item named widget in the +folder products would be /products/widget.
  • +

The content repository adds an additional twist to a traditional +filesystem: any content item, not just a folder, may serve +as a container for any number of other content items. For example, +imagine a book consisting of a preface, a number of chapters and a +bibliography (which in turn may have any number of entries). The +book itself is a content item, in that it has attributes +(publisher, ISBN number, publication date, synopsis, etc.) +associated with it. It also is the logical container for all its +components.

It is important to note that folders are simply a special +subtype of content item. The content repository's representation of +a parent-child relationship between a folder and the items it +contains is no different from the relationship between a book and +its chapters. Folders may be thought of simply as generic +containers for grouping items that are not necessarily part of a +greater whole.

An Example

Consider a simple repository structure with the following +contents:

Note the following:

    +
  • The root folder of the content repository has a special ID +which is returned by the function +content_item.get_root_folder.
  • Regular content items such as index and about +may be stored directly under the root folder.
  • The "About Us" page has a photo as a child item. Note that the +path to the photo is /about/photo. Internally, the photo's +parent_id (in the cr_items table) is set to the +item_id of the "About Us" page.
  • The "Press" folder contains two items. Internally, the +parent_id of the "Press Index" and "Release One" items are +set to the item_id of the "Press" folder.
  • +

Note that the same effective organization could have been +achieved by creating the "Press Index" item under the root, and +having press releases as its children. Using the folder approach +may have the following advantages:

    +
  • Content management systems can take advantage of the folder +structure to implement an intuitive user interface analagous to +familiar desktop tools (Windows Explorer, MacOS Finder, etc.).
  • You can use the content repository API to constraint the type +of content that a folder may contain (except for the index page). +For example, it is possible to limit the contents of the "Press" +folder to items of type "Press Release." See the Content Folder API for more details.
  • +

Using your own root

By default, the content repository has one root folder for +content items and one for templates. In some situations, that is +not enough. For example, a package that can be instantiated several +times might wish to store the content for each instance in its own +content root. Creating your own content (and template) root also +has the advantage that you will not accidentally access another +package's content nor will another package access your content. Not +that that could do any harm, because you have secured all your +content through appropriate permissions.

We only talk about creating content roots from here on — +creating template roots is completely analogous. You create your +own content root by calling content_folder.new in +PL/SQL:

+declare
+  v_my_content_root integer;
+begin
+  v_my_content_root := content_folder.new(
+     name => 'my_root', 
+     label => 'My Root', 
+     parent_id => 0
+  );
+  -- Store v_my_content_root in a safe place
+end;
+/ 
+

The important point is that you have to pass in 0 for +the parent_id. This parent_id is special in that +it indicates folders with no parent.

The content repository does not keep track of who created what +root folders. You have to do that yourself. In the above example, +you need to store the value v_my_content_root somewhere, +for example a table that is specific for your package, otherwise +you won't have a reliable way of accessing your new content +root.

With multiple content roots, there can be many items with +item_path'/news/article' and you need to tell +the content repository which root you are talking about. For +example, to retrieve content through content_item.get_id, +you pass the id of your content root as the root_folder_id +parameter to specify the content root under which the +item_path should be resolved.


karlg@arsdigita.com
+Last Modified: $Id: file-system.html,v 1.1.1.1 2001/03/13 22:59:26 +ben Exp $ + Index: openacs-4/packages/acs-content-repository/www/doc/guide/items.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/guide/items.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/guide/items.adp 16 Sep 2014 20:51:13 -0000 1.1.2.1 @@ -0,0 +1,46 @@ + +{/doc/acs-content-repository {Content Repository}} {Content Repository Developer Guide: Creating Content +Items} +Content Repository Developer Guide: Creating Content +Items + + + +

Creating Content Items

+Content Repository : Developer +Guide

Use the Content Item API to create the item

Content items are initialized using the +content_item.new function. A name is the only parameter +required to create an item:

+item_id := content_item.new( name => 'my_item' );
+

The name represents the tail of the URL for that content item. +In most cases you will want to create items in a particular context +with the repository hierarchy:

+item_id := content_item.new(
+   name      => 'my_item', 
+   parent_id => :parent_id
+);
+

The parent ID must be another content item, or a subclass of +content item such as a folder.

The content_item.new function accepts a number of other +optional parameters. The standard creation_date, +creation_user and creation_ip should be specified +for auditing purposes. You can also create the initial revision and +publish text items in a single step:

+item_id := content_item.new(
+   name      => 'my_item', 
+   parent_id => :parent_id,
+   title     => 'My Item',
+   text      => 'Once upon a time Goldilocks crossed the street.  
+                 Here comes a car...uh oh!  The End',
+   is_live   => 't'
+);
+

If either the title or text are not null, the function will +create the first revision of the item. It will also mark the item +as live if the is_live parameter is true. The alternative +to this one step method is to create a content item and then add a +revision using the Content Revision API.

Publishing a content item

If a content item has at least one revision, then it can be +published by calling the content_item.set_live_revision +procedure, which takes as input a revision_id:

+content_item.set_live_revision( revision_id => :revision_id );
+

karlg@arsdigita.com

Last Modified: $Id: items.html,v 1.1.1.1 2001/03/13 22:59:26 ben +Exp $

+ Index: openacs-4/packages/acs-content-repository/www/doc/guide/keywords.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/guide/keywords.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/guide/keywords.adp 16 Sep 2014 20:51:13 -0000 1.1.2.1 @@ -0,0 +1,132 @@ + +{/doc/acs-content-repository {Content Repository}} {Content Repository Developer Guide: Subject Keywords +(Categories)} +Content Repository Developer Guide: Subject Keywords +(Categories) + + + +

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/ProcedurePurposeDescription
newCreate a new Subject KeywordThis 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)
deleteDelete a Subject KeywordThis is a standard delete function, used to delete a +Subject Keyword
+get_heading
set_heading
get_description
set_description +
Manipulate properties of the KeywordYou 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 ItemsThese 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".
  • +
+
+ Index: openacs-4/packages/acs-content-repository/www/doc/guide/object-relationships.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/guide/object-relationships.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/guide/object-relationships.adp 16 Sep 2014 20:51:13 -0000 1.1.2.1 @@ -0,0 +1,95 @@ + +{/doc/acs-content-repository {Content Repository}} {Content Repository Developer Guide: Object +Relationships} +Content Repository Developer Guide: Object +Relationships + + + +

Object Relationships

+Content Repository : Developer +Guide

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:

    +
  • News stories may be linked to other stories on the same +topic.
  • An article may be linked to any number of photos or charts that +are embedded in the article.
  • A long article is divided into multiple sections, each of which +is intended for separate display.
  • Product reviews are linked to specific products.
  • User portraits are linked to specific users.
  • +

The ACS kernel provides a standard, highly flexible data model +and API for relating objects to other objects. If you have a highly +specific problem and are developing your own user interface on the +content repository, you can use the ACS relationships framework +directly. The relationship framework in the content repository +itself is simply intended as a convenience for handling common +relationship situations involving content items.

Parent-Child Relationships

In many cases one content item may serve as a natural container +for another item. An article divided into sections, or a news story +with an associated photo are one example of this. These +"parent-child" relationships are handled by the basic hierarchical +organization of the content repository. Every item has a parent +item, represented internally by the parent_id column in +the cr_items table.

It is often desirable to constrain the number and content type +of child items. For example, the specifications for a news story +may only allow for a single photo. A structured report may have +exactly three sections. Furthermore, it may be necessary to +classify or identify child items of the same type. Clearly the +sections of a report would have a logical order in which they would +need to be presented to the user. The layout for a photo album may +have a special position for a "featured" photo.

+ +

The content repository accomodates these situations in the +following ways:

    +
  • An API procedure, content_type.register_child_type, +may be used to specify the minimum and maximum number of children +of a particular content type that an item may have. You may +optionally specify a "tag" for identifying child items of the same +type. For example, you may want to allow only 1 image with the +"featured" tag, and up to 8 other images without this.
  • A Boolean API function, content_item.is_valid_child, +which checks all registered child constraints on the content type +of an item and returns true if it is currently possible to add an +child of a particular type to tan item. Note that this function +does not protect against concurrent transactions; it is only +foolproof if you lock the cr_child_rels table +beforehand.
  • A mapping table, cr_child_rels, which contains two +attributes, order_n and relation_tag, that may be +used to characterize the parent-child relationship. Parent-child +relationships are themselves treated as ACS Objects, so this table +may be extended with additional attributes as required by the +developer.
  • +

Note that there is no currently no explicit API to "add a +child." You specify the parent of an item upon creating it. You can +use the API procedure content_item.move to change the +parent of an item.

Item-Object Relationships

In addition to the relationships to their parents and children +in the content repository hierarchy, content items may be linked to +any number of other objects in the system. This may include +products, users or content items on related subjects.

The same need to constrain the possibilities for an item-object +relationship, as described above for parents and children, also +apply to items and objects in general. The content repository +provides a data model and API for managing these constraints that +parallels what is provided for parent-child relationships:

    +
  • An API procedure, content_type.register_relation_type, +may be used to specify the minimum and maximum number of relations +with a particular object type that an item may have. There is no +limitation on the type of objects that may be related to content +items. If you wish to relate content items to other content items, +however, the object type should specify a content type (a subtype +of content_revision) rather than simply +content_item. As for parent-child relationship +constraints, ou may optionally specify a "tag" for identifying +related objects of the same type.
  • A Boolean API function, +content_item.is_valid_relation, which checks all +registered constraints on the content type of an item and returns +true if it is currently possible to relate an object of a +particular type to an item.
  • A mapping table, cr_item_rels, which contains two +attributes, order_n and relation_tag, that may be +used to characterize the item-object relationship. Item-object +relationships are themselves treated as ACS Objects, so this table +may be extended with additional attributes as required by the +developer.
  • +

Extending Parent-Child and Item-Object Relationships

The simple relation mechanisms described above may not be +sufficient for some applications. However, because both +relationships defined by the content repository are +themselves objects, you have the option to extend their +types as you would for any other ACS object.


karlg@arsdigita.com
+Last modified: $Id: object-relationships.html,v 1.1.1.1 +2001/03/13 22:59:26 ben Exp $ + Index: openacs-4/packages/acs-content-repository/www/doc/guide/publish.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/guide/publish.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/guide/publish.adp 16 Sep 2014 20:51:13 -0000 1.1.2.1 @@ -0,0 +1,98 @@ + +{/doc/acs-content-repository {Content Repository}} {Content Repository Developer Guide: Publishing +Content} +Content Repository Developer Guide: Publishing +Content + + + +

Publishing Content

+Content Repository : Developer +Guide

The content repository does not place any restrictions on the +methods employed for delivering content via a public server +infrastructure. Applications are free to query the repository and +process the data in any way desired.

Although there are no restrictions on publishing methodology, +the repository API is intended to facilitate generic template-based +publication, regardless of the specific presentation layer used. +The following diagram illustrates the steps typically involved in +such a publication process:

In general, there is an initial resolution step in +which the server must identify the appropriate content item and +then decide which template to actually parse. Following that is an +execution step, during which setup tasks associated with +the template are performed. Finally, the merging step +combines the data and layout into a rendered page.

Matching URLs to Content Items

The primary mechanism for matching URLs to Content Items are +virtual URL handlers, .vuh files. An explanation +of virtual URL handlers can be found in the tutorial on the +Request Processor.

Here is an example index.vuh file that you can adapt to +your own purposes:

+# Get the paths
+
+set the_url [ad_conn path_info]
+set the_root $::acs::pageroot
+
+# Get the IDs
+set content_root \
+  [db_string content_root "select content_item.get_root_folder from dual"]
+set template_root \
+  [db_string template_root "select content_template.get_root_folder from dual"]
+
+# Serve the page
+# DRB: Note that content::init modifies the local variable the_root, which is treated
+# as though it's been passed by reference.   This requires that the redirect treat the
+# path as an absolute path within the filesystem.
+if { [content::init the_url the_root $content_root $template_root] } {
+  set file "$the_root/$the_url"
+  rp_internal_redirect -absolute_path $file
+} else {
+  ns_returnnotfound
+}
+

The content_root and template_root parameters +select the content and template root folders. In the example, they +are just the default roots that the content repository initializes +on installation. If you want to store your content completely +independent from that of other packages, you can initialize your +own content root and pass that folder's ID on to +content::init.

To publish content through URLs that are underneath +/mycontent you need to do the following:

    +
  1. Create a directory mycontent in your server's page +root and an index.vuh file in that directory.
  2. Adapt the set content_root ... and set +template_root .. statements in the example above so that they +are being set to the content and template root folders that you +want to publish content from.
  3. Change the set the_url ... statement so that the +variable the_url contains the absolute path to the content +item you wish to serve from your (or the default) content +root.
  4. +

If you use the example index.vuh file above unaltered +for requests to my_content, a request for +http://yourserver/mycontent/news/articles/42 would request +the content item /news/articles/42 from the content +repository on the default content root folder.

Matching Content Items to Templates

Querying Content

Querying Attributes

When you create a new content type or add an attribute to an +existing content type, a view is created (or recreated) that joins +the attribute tables for the entire chain of inheritance for that +content type. The view always has the same name as the attribute +table for the content table, with an "x" appended to distinguish it +from the table itself (for example, if the attribute table for +Press Releases is press_releases, then the view +will be named press_releasesx. Querying this view is a +convenient means of accessing any attribute associated with a +content item.

As a shortcut, the item's template may call +content::get_content in its Tcl file in order to +automatically retrieve the current item's attributes. The +attributes will be placed in a onerow datasource called +content . The template may then call +template::util::array_to_vars content in order to convert +the onerow datasource to local variables.

In addition to the "x" view, the Content Repository creates an +"i" view, which simplifies the creation of new revisions. The "i" +view has the same name as the content table, with "i" appended at +the end. You may insert into the view as if it was a normal table; +the insert trigger on the view takes care of inserting the actual +values into the content tables.

Querying Additional Data

Templates often display more than simple content attributes. +Additional queries may be necessary to obtain data about related +objects not described directly in attribute tables. The setup code +associated with a template typically performs these queries after +the initial query for any needed attributes.

Merging Data with Templates

Returning Output

    +
  1. Write to the file system
  2. Service public requests directly
  3. +

karlg@arsdigita.com
+Last Modified: $Id: publish.html,v 1.4 2013/04/12 16:12:56 gustafn +Exp $ + Index: openacs-4/packages/acs-content-repository/www/doc/guide/revisions.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/guide/revisions.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/guide/revisions.adp 16 Sep 2014 20:51:13 -0000 1.1.2.1 @@ -0,0 +1,100 @@ + +{/doc/acs-content-repository {Content Repository}} {Content Repository Developer Guide: Creating Content +Revisions} +Content Repository Developer Guide: Creating Content +Revisions + + + +

Creating Content Revisions

+ACS Documentation : Content Repository : Developer Guide

At a basic level, creating a new revision of a content item +involves the following steps:

    +
  1. Insert a row in the acs_objects table to create the +object.
  2. Insert a corresponding row in the cr_revisions table +with the basic attributes for the revision.
  3. Write the content data into the content BLOB column of +the cr_revisions table.
  4. Insert a corresponding row into the attribute table of each +ancestor of the content type of the item. This is not applicable if +the content type is Basic Item or an immediate subtype +thereof.
  5. Insert a corresponding row into the attribute table of the +content type of the item. This is not applicable if the content +type is Basic Item.
  6. +

Use the Content Revision API to create a revision

Content revisions are initialized using the +content_revision.new function. The only parameters +required to create the revision are a title, a content item ID, and +some text:

+revision_id := content_revision.new( 
+    title   => 'A Revision',
+    item_id => :item_id,
+    text    => 'Once upon a time Goldilocks crossed the street.
+                Here comes a car...uh oh!  The End'
+);
+

The item_id parameter is ID of the content item with +which the revision is associated.

The content_item.new function accepts a number of other +optional parameters: description, mime_type, and +publish_date. The standard creation_date, +creation_user, and creation_ip should be +specified for auditing purposes. Instead of the text +parameter, this function can be called with a data +parameter, in which data is a blob:

+revision_id := content_revision.new(
+    title         => 'A Revision',
+    description   => 'A Description of a revision',
+    mime_type     => 'text/html',
+    publish_date  => to_date('Jan 22, 2000','Mon DD, YYYY'),
+    item_id       => :item_id,
+    data          => :blob_of_content,
+    creation_date => sysdate,
+    creation_user => :user_id,
+    creation_ip   => :ip_address
+);
+

Insert additional attributes

Given that there is no way (AFAIK) to pass variable parameters +to a PL/SQL function, there is no way to make +content_revision.new generic enough to support submission +of the attributes for all different content types. This leaves you +with three alternatives:

    +
  1. Call content_revision.new followed by manual DML +statements to write data into the content BLOB and insert +attributes.
  2. Write a PL/SQL package for each of your content types, which +encapsulates the above code.
  3. Create revisions by inserting into the attribute view for each +content type.
  4. +

The last option is made possible by an instead of +insert trigger on the attribute view for each content type. +(An attribute view joins together the storage tables for +the ancestors of each content type, including acs_objects +and cr_revisions). Normally it is not possible to insert +into a view. Oracle allows you to create an instead of +trigger for a view, however, which intercepts the DML statement and +allows you to execute an arbitrary block of PL/SQL instead. The +code to create or replace the trigger is automatically generated +and executed with each call to +content_type.create_attribute. The trigger makes it +possible to create complete revisions with a single insert +statement:

+insert into cr_revisionsx (
+  item_id, revision_id, title
+) values (
+  18, 19, 'All About Revisions'
+);
+

Because a special trigger is generated for each content type +that includes insert statements for all inherited tables, revisions +with extended attributes may be created in the same fashion:

+insert into cr_imagesx (
+  item_id, revision_id, title, height, width
+) values (
+  18, 19, 'A Nice Drawing', 300, 400
+);
+

Inserting content via file or text upload

Selecting a live revision

The live revision of a content item can be obtained with the +content_item.get_live_revision function:

+live_revision_id := content_item.get_live_revision(
+    item_id => :item_id
+);
+

The item_id identifies the content item with which the +revision is associated.

Likewise, the most recent revision of a content item can be +obtained with the content_item.get_latest_revision +function:

+latest_revision_id := content_item.get_latest_revision(
+    item_id => :item_id
+);
+

karlg@arsdigita.com

Last Modified: $Id: revisions.html,v 1.1.1.1 2001/03/13 22:59:26 +ben Exp $

+ Index: openacs-4/packages/acs-content-repository/www/doc/guide/search.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/guide/search.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/guide/search.adp 16 Sep 2014 20:51:13 -0000 1.1.2.1 @@ -0,0 +1,94 @@ + +{/doc/acs-content-repository {Content Repository}} {Content Repository Developer Guide: Search} +Content Repository Developer Guide: Search + + + +

Search

+Content Repository : Developer +Guide

The content repository provides a consistent sitewide interface +for searching content. It uses Intermedia to index the +content column of cr_revisions) as well as all +the attribute columns for each content type.

Searching Content

The content column in cr_revisions may contain +data in any text or binary format. To accomodate searches across +multiple file types, the content repository uses an Intermedia +index with the INSO filtering option. The INSO filter automatically +detects the the file type of a binary object, and extracts text +from it for indexing. Most common file types are supported, +including PDF and Microsoft Word, and Excel and PowerPoint.

Searching for content requires the same syntax as any text +index:

+select
+  score(1), revision_id, item_id
+from
+  cr_revisions r
+where
+  contains(content, 'company', 1) > 0
+

The above query may be useful for an administrative interface +where you wish to search across all revisions, but in most cases +you only want to search live revisions:

+select
+  score(1), revision_id, item_id, content_item.get_path(item_id) url, title
+from
+  cr_revisions
+where
+  contains(content, 'company', 1) > 0
+and
+  revision_id = content_item.get_live_revision(item_id)
+

The URL and title may be used to construct a hyperlink directly +to the item.

You may implement any number of variants on this basic query to +place additional constraints on the results, such as publication +date, content type, subject heading or a particular attribute (see +below).

Some limitations of the current implementation include:

    +
  • Multilingual searches are not enabled by default. You may +enable them for one more languages by setting the appropriate +Intermedia preferences when creating +cr_rev_content_index.
  • Some items are not appropriate to display "stand-alone", but +rather need to appear only in the context of a container document +(typically their parent in the content repository). This is +probably a limitation of content_item.get_path: it should +be possible to specify an arbitrary function to return the path for +items of a particular content type, with +content_item.get_path as the default.
  • +

Searching Attributes

This task is primarily handled to two Intermedia indices:

Providing a generic mechanism for searching attributes is +complicated by the fact that the attributes for each content type +are different. The content repository takes advantage of the XML +features in Oracle 8.1.6 to address this:

    +
  1. After creating a new revision and inserting attributes into the +storage table for the content type and all its ancestors, you must +execute the content_revision.index_attributes procedure. +(Note that this cannot be called automatically by +content_revision.new, since the attributes in all extended +storage tables must be inserted first).

  2. This procedure creates a row in the +cr_revision_attributes table, and writes an XML document +including all attributes into this row. A Java stored procedure +using the Oracle XML Parser for Java v2 is used to actually +generate the XML document.

  3. A special Intermedia index configured to parse XML documents is +built on the column containing the XML documents for all +revisions.

  4. +

The Intermedia index allows you to use the WITHIN operator to +search on individual attributes if desired.

+select 
+  revision_id,score(1) 
+from 
+  cr_revisions 
+where 
+  contains(attributes, 'company WITHIN title', 1) > 0
+

Some limitations of the current implementation include:

    +
  1. A USER_DATASTORE associated with each row of the +cr_items table, which feeds Intermedia the contents of the +content column (a BLOB) for the live revision of +an item. This should theoretically be more efficient for searching +live content, especially in production environments where content +is revised often.
  2. A second USER_DATASTORE associated with each row of +the cr_items table, which feeds Intermedia the XML +document representing all attributes for the live revision +of an item (from cr_revision_attributes).
  3. The default XML document handler for the content repository +simply provides a flat file of all attributes. Content types should +also be able implement custom handlers, to allow the XML document +to reflect one-to-many relationships or special formatting of +attributes as well. The handler should specify a java class and +method, which a dispatch method can call by reflection.
  4. +

karlg@arsdigita.com
+Last Modified: $Id: search.html,v 1.1.1.1 2001/03/13 22:59:26 ben +Exp $ + Index: openacs-4/packages/acs-content-repository/www/doc/guide/storage.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/guide/storage.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/guide/storage.adp 16 Sep 2014 20:51:14 -0000 1.1.2.1 @@ -0,0 +1,103 @@ + +{/doc/acs-content-repository {Content Repository}} {} + + + + +

Storing Data in the Content Repository


This document provides an introduction to using the content +repository for storing data (binary or text files) and associated +attributes. It describes how to store user portraits as an +example.

Define an Item Type

The first step towards using the content repository is to define +one or more content types for the data you wish to +manage.

The basic content item includes the following attributes:

    +
  • Title
  • Description
  • Publication or Posting Date
  • Author or Contributor
  • MIME Type
  • Binary or Text Data
  • +

Most types of content require additional attributes. For a +photo, we probably also want to store the pixel width and height at +the very least:

+  create table images (
+    image_id       integer
+                   constraint images_image_id_fk
+                   references cr_revisions
+                   constraint images_pk
+                   primary key,
+    width          integer,
+    height         integer
+  );
+

Content types are nothing more than standard ACS Objects that +inherit from content_revision:

+begin
+
+ acs_object_type.create_type (
+   supertype => 'content_revision',
+   object_type => 'image',
+   pretty_name => 'Image',
+   pretty_plural => 'Images',
+   table_name => 'images',
+   id_column => 'image_id',
+   name_method => 'acs_object.default_name'
+ );
+
+ acs_attribute.create_attribute (
+   object_type => 'image',
+   attribute_name => 'width',
+   datatype => 'number',
+   pretty_name => 'Width',
+   pretty_plural => 'Widths'
+ );
+
+ acs_attribute.create_attribute (
+   object_type => 'image',
+   attribute_name => 'height',
+   datatype => 'number',
+   pretty_name => 'Height',
+   pretty_plural => 'Heights'
+ );
+
+end;
+/
+show errors
+

Note that content types always extend content_revision, +rather than content_item. This is because we want to store +multiple revisions of both the actual data (in this case the image) +as well as associated attributes (the width and height of the image +may vary among revisions).

Define a Relationship to a Target Object

The content repository implements a flexible mechanism for +organizing data in a hierarchical fashion in a manner similar to a +file system. This would be useful if we ever decided to allow each +user to manage an entire personal photo gallery rather than a +single portrait.

In the simple case where each user is allowed a single portrait, +we can simply define a relationship between user and image as ACS +Objects:

+  acs_rel_type.create_role('user');
+  acs_rel_type.create_role('portrait');
+
+  acs_rel_type.create_type( rel_type => 'user_portrait_rel',
+     pretty_name => 'User Portrait',
+     pretty_plural => 'User Portraits',
+     object_type_one => 'user',
+     role_one => 'user',
+     min_n_rels_one => 1,
+     max_n_rels_one => 1,
+     object_type_two => 'content_item',
+     min_n_rels_two => 0,
+     max_n_rels_two => 1
+  );
+

Note that the user object is related to a +content_item object rather than an image object +directly. Each image object represents only a single +revision of a portrait. Revisions always exist in the context of an +item.

Store Objects

Now we have defined both a content type and relationship type, +we can start storing portraits. The DML for processing a new +portrait upload form would look like this:

+  begin transaction
+    :item_id := content_item.new(:name, :item_id, sysdate, NULL,                           '[ns_conn peeraddr]'); 
+    # maybe have content_revision return the LOB locator so that it can
+    # be used directly with blob_dml_file
+    :revision_id := content_revision.new(:title, :description, $publish_date,                               :mime_type, NULL, :text, 'content_revision', 
+                               :item_id, :revision_id);
+    blob_dml_file update cr_revisions set content = empty_blob() ...
+    :rel_id := acs_rel.new(...)
+

Retrieve Objects

+  ns_ora write_blob ...
+

karlg@arsdigita.com

Last Modified: $Id: storage.html,v 1.1.1.1 2001/03/13 22:59:26 +ben Exp $

+ Index: openacs-4/packages/acs-content-repository/www/doc/guide/template.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/guide/template.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/guide/template.adp 16 Sep 2014 20:51:14 -0000 1.1.2.1 @@ -0,0 +1,112 @@ + +{/doc/acs-content-repository {Content Repository}} {Content Repository Developer Guide: Applying +Templates} +Content Repository Developer Guide: Applying +Templates + + + +

Applying Templates

+Content Repository : Developer +Guide

The content repository allows you to associate templates with +both content types and individual content items. A template +determines how a content item is rendered when exported to the file +system or served directly to a client.

The content repository does not make any assumptions about the +type of templating system used by the application server with which +it is being used. Templates are simply made available to the +application server as text objects. The server is responsible for +merging the template with the actual content.

Creating templates

The content repository handle templates as a special class of +text object. The interface for handling templates builds on that of +simple content items:

+template_id := content_template.new(
+    name          => 'image_template',
+    parent_id     => :parent_id
+);
+

The name represents the tail of the location for that content +template. The parent ID must be another content item, or a subclass +of content item such as a folder.

+The content_template.new function accepts the standard +creation_date, creation_user, and +creation_ip auditing parameters.

Content items and templates are organized in two separate +hierarchies within the content repository. For example, you may +place all your press releases in the press folder under +the item root (having the ID returned by +content_item.get_root_folder). You may have 5 different +templates used to render press releases. These my be stored in the +press folder under the template root (having the +ID returned by content_template.get_root_folder).

Templates are placed under their own root to ensures that bare +templates are never accessible via a public URL. This is also done +because the relationship with the file system may be different for +templates than for content items. For example, templates may be +associated with additional code or resource files that developers +maintain under separate source control.

Associating templates with content types

You use the content_type.register_template procedure to +associate a template with a particular content type:

+content_type.register_template(
+  content_type => 'content_revision',
+  template_id  => :template_id,
+  use_context  => 'public',
+  is_default   => 't'
+);
+

The use_context is a simple keyword that specifies the +situation in which the template is appropriate. One general +context, public, is loaded when the content repository is +installed. Templates in this context are for presenting content to +users of the site. Some sites may wish to distinguish this further, +for example using intranet, extranet and +public contexts.

The is_default flag specifies that this template will +serve as the default template in the case that no template is +registered to a content item of this content type and this use +context. Any content type/context pair may have any number of +templates registered to it, but there can be only one default +template per pair.

To make a template the default template for a content +type/context pair:

+content_type.set_default_template(
+    content_type => 'content_revision',
+    template_id  => :template_id,
+    use_context  => 'public'
+);
+

Associating templates with content items

Individual items may also be associated with templates using the +content_item.register_template procedure:

+content_item.register_template(
+  item_id     => :item_id,
+  template_id => :template_id,
+  use_context => 'intranet'
+);
+

Unlike the case with content types, only one template may be +registered with a content item for a particular context.

The content management system uses this functionality to allow +publishers to choose templates for each content they create. For +example, a company may have three different templates for +presenting press releases. Depending on the subject, geographic +region or any other criterion, a different template may be used for +each press release.

Retrieving the template for a content item

The application server (AOLserver or servlet container) may use +the content_item.get_template function to determine the +proper template to use for rendering a page in any particular +context:

+template_id := content_item.get_template(
+    item_id     => :item_id, 
+    use_context => 'public'
+);
+
+template_path := content_template.get_path(
+    template_id => :template_id
+);
+

In the case that no template is registered to given item/context +pair, content_item.get_template will return the default +template (if it exists) for the related content type/context +pair.

Unregistering templates

The procedure for disassociating templates with content types is +as follows:

+content_type.unregister_template(
+    content_type => 'content_revision',
+    template_id  => :template_id,
+    use_context  => 'intranet'
+);
+

The corresponding procedure to disassociate templates with +content items is:

+content_item.unregister_template(
+    item_id     => :item_id,
+    template_id => :template_id,
+    use_context => 'admin'
+);
+

karlg@arsdigita.com

Last Modified: $Id: template.html,v 1.1.1.1 2001/03/13 22:59:26 +ben Exp $

+ Index: openacs-4/packages/acs-content-repository/www/doc/guide/types.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/guide/types.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/guide/types.adp 16 Sep 2014 20:51:14 -0000 1.1.2.1 @@ -0,0 +1,99 @@ + +{/doc/acs-content-repository {Content Repository}} {Content Repository Developer Guide: Defining Content +Types} +Content Repository Developer Guide: Defining Content +Types + + + +

Defining Content Types

+Content Repository : Developer +Guide

The content repository requires you to define each type of +content supported by your supplication. Content types are defined +as ACS Object Types, and may be created in the same +fashion as any other object type. This page provides some specific +examples and details related to defining ACS object types in the +context of the content repository.

Determine content attributes

A content item typically consists of two components:

    +
  1. Text or binary data stored as a single object
  2. Structured attributes stored as distinct values
  3. +

Note that a content type does not have to store its +primary content in the BLOB column of the +cr_revisions table. There is some additional overhead +associated with retrieving small passages of text from the BLOB +column compared to an attribute column. In most cases the +difference is trivial (fewer than about 10 microseconds), but if +many items must be queried at the same time the difference may +become significant. If the primary content will always be small, it +is perfectly acceptable to store the content in an attribute column +instead.

Basic attributes for all content types are stored in the +cr_revisions (note that they are stored in the revisions +table so that attributes may be updated for each new revision of +the actual data). Most types of content require more than the basic +attributes. For example, when storing images you will usually want +to store the pixel height and width so that images can be selected +and sorted by size, as well as displayed efficiently.

Create an attribute table

Extended attributes associated with ACS object types may be +stored as key-value pairs in a central table (generic storage), or +in a custom table whose primary key references the associated ACS +object ID (specific storage). To ensure efficient access to +attributes, the content repository API requires you to use specific +storage. Your table should have the form:

+create table cr_content_type (
+    content_type_id       integer
+                          constraint cr_content_type_id_fk
+                          references cr_revisions
+                          constraint cr_content_type_pk
+                          primary key,
+    attributes...
+);
+

Note that your extended attribute table must reference the +cr_revisions table, notcr_items. As +mentioned above, this allows you to maintain multiple revisions of +the attribute data in tandem with revisions of the content object +itself.

Use the Content Type API to create the content type

To define a content type, you should write an SQL script to +create the content type and then add attributes to it:

+declare
+ attr_id        acs_attributes.attribute_id%TYPE;
+begin
+
+ -- create the content type
+ content_type.create_type (
+   content_type  => 'cr_press_release',
+   pretty_name   => 'Press Release',
+   pretty_plural => 'Press Releases',
+   table_name    => 'cr_press_releases',
+   id_column     => 'release_id'
+ );
+
+ -- create content type attributes
+ attr_id := content_type.create_attribute (
+   content_type   => 'cr_press_release',
+   attribute_name => 'location',
+   datatype       => 'text',
+   pretty_name    => 'Location',
+   pretty_plural  => 'Location',
+   column_spec    => 'varchar2(1000)'
+ );
+
+ ...
+

The content_type methods use the core ACS Object Type +API to create an object type for each content type, and to add +attributes to the object type. In addition, +content_type.create_type will create the extended +attribute table with an appropriately defined primary key column +(referencing its supertype) if the table does not already exist. +Likewise, content_type.create_attribute will add a column +to the table if the column does not already exist.

Most importantly, the content_type methods call +content_type.refresh_view after each change to the content +type definition. Each content type must have an associated +attribute view named +table_namex, where +table_name is the name of the extended attribute +table for a particular content type. The view joins the +acs_objects, cr_revisions, and all extended +attribute tables in the class hierarchy of a particular content +type. This view may be used to query attributes when serving +content.

Creating compund items

In many cases your content items will serve as containers for +other items. You can include the set of allowable components as +part of a content type definition. See Object Relationships for +details.


templating@arsdigita.com

Last Modified: $Id: types.html,v 1.1.1.1 2001/03/13 22:59:26 ben +Exp $

+ Index: openacs-4/packages/acs-content-repository/www/doc/guide/workflow.adp =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-content-repository/www/doc/guide/workflow.adp,v diff -u -N --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-content-repository/www/doc/guide/workflow.adp 16 Sep 2014 20:51:14 -0000 1.1.2.1 @@ -0,0 +1,161 @@ + +{/doc/acs-content-repository {Content Repository}} {Content Repository Developer Guide: Workflow} +Content Repository Developer Guide: Workflow + + + +

Applying Workflow to Content Items

+Content Repository : Developer +Guide

This document describes the workflow API calls necessary to +apply a simple workflow to a content item.

Workflow Description

Most publishers wish to follow some variation of the following +workflow:

+ + + + + + + + + + + +
StateTaskDescription
CreatedAuthoringThe publisher has created the item.
AuthoredEditingThe author has written the item.
EditedPublishingThe editor has approved the item.
PublishedNoneThe publisher has approved the item.

At any point in the workflow, an assigned user should be able to +check out an item, such that other users are advised that someone +is working on it. When checking an item in, a user should have up +to three options:

    +
  1. Check the item in but do not mark the task as finished +(allowing someone else to work on the task. The currently enabled +task (whether it is authoring, editing or approving) does not +change.
  2. Check the item in and move to the next task. For the authoring +task, this signifies that the authoring is complete. For subsequent +tasks, this signifies approval.
  3. Check the item in and move to a previous task, indicating +rejection.
  4. +

This simple workflow is defined in +sql/workflows/author-edit-publish.sql.

Workflow Creation

Production of a content item frequently begins with a concept +which is initiated by the publisher and then executed by the staff. +In this scenario, the publisher creates the workflow and then +assigns each task in the workflow to one or more people. The API +calls to initialize a new workflow are as follows:

+declare
+  v_case_id integer;
+  sample_object_id integer := 9;
+  sample_user_id integer := 10;
+begin
+
+  v_case_id := workflow_case.new(  workflow_key => 'publishing_wf', 
+                                   context_key => NULL, 
+                                   object_id => sample_object_id);
+
+  workflow_case.add_manual_assignment(v_case_id, 'authoring', sample_user_id);
+  workflow_case.add_manual_assignment(v_case_id, 'editing', sample_user_id);
+  workflow_case.add_manual_assignment(v_case_id,'approval', sample_user_id);
+
+  workflow_case.start_case(case_id => v_case_id, msg => 'Here we go.');
+
+end;
+/
+

In this case, only one assignment is made per task. You can make +as many assignments per task as desired. There is currently no +workflow API to set deadlines, so you must write your own DML to +insert a row into wf_case_deadlines if you wish to allow +the publisher to set deadlines ahead of time.

The above workflow is created in the Default context. In +practice, you may wish to create one or more contexts in which to +create your workflows. Contexts may be used to represent different +departments within an organization.

The start_case enables the first task in the workflow, +in this case Authoring.

Check Out Item

If multiple persons are assigned to the same task, it is useful +to allow a single person to "check out" or lock an item while they +are working. This is accomplished with the following API calls:

+declare
+  v_journal_id integer;
+  sample_task_id := 1000;
+  sample_user_id := 10;
+  sample_ip := '127.0.0.1';
+begin
+  
+  v_journal_id := workflow_case.begin_task_action(sample_task_id, 'start', 
+    sample_ip, sample_user_id, 'Checking it out');
+  workflow_case.end_task_action(v_journal_id, 'start', sample_task_id);
+
+end;
+/
+

A mininum of two calls are required to perform any action +related to a task. In this case we are simply notifying the +workflow engine that someone has started the task. You may specify +NULL for the journal message if the user does not wish to comment +on the check out.

Check In Item

Unless given a timeout period, a lock on a content item will +persist until the holding user checks the item back in. This +involves notifying the workflow engine that the user has finished +the task:

+declare
+  v_journal_id integer;
+  sample_task_id integer := 1000;
+  sample_user_id integer := 10;
+  sample_ip := '127.0.0.1';
+begin
+  
+  v_journal_id := workflow_case.begin_task_action(sample_task_id, 'finish', 
+    sample_ip, sample_user_id, 'Done for now');
+  workflow_case.set_attribute_value(v_journal_id, 'next_place', 'start');
+  workflow_case.end_task_action(v_journal_id, 'finish', sample_task_id);
+
+end;
+/
+

Upon finishing a task, you must notify the workflow engine where +to go next. In this case, an author wishes to simply check an item +back in without actually completing the authoring task. The +set_attribute_value procedure must thus be used to set +next_place to the starting place of the workflow.

Finish Task

The process to finish a task varies slightly depending on +whether the user has previously checked out the item out or not. If +the user has not already checked it out (has been working on the +item without locking it, the code looks like this:

+declare
+  v_journal_id integer;
+  sample_task_id integer := 1002;
+  sample_user_id integer := 10;
+  sample_ip := '127.0.0.1';
+begin
+  
+  -- start the task
+  v_journal_id := workflow_case.begin_task_action(sample_task_id, 'start', 
+    sample_ip, sample_user_id, NULL);
+  workflow_case.end_task_action(v_journal_id, 'start', sample_task_id);
+
+  -- finish the task
+  v_journal_id := workflow_case.begin_task_action(sample_task_id, 'finish', 
+    sample_ip, sample_user_id, 'Authoring complete');
+  workflow_case.set_attribute_value(v_journal_id, 'next_place', 'authored');
+  workflow_case.end_task_action(v_journal_id, 'finish', sample_task_id);
+
+end;
+/
+

In this case an author is finishing the Authoring task, +upon which the workflow engine will move the workflow to the +Authored state (as indicated by the next_place +attribute). If the author had previously checked out the item, then +only the second step is required.

Approve or Reject

Approval steps more commonly do not involve an explicit +check-out process. The code is thus virtually identical to that +above:

+declare
+  v_journal_id integer;
+  sample_task_id integer := 1003;
+  sample_user_id integer := 10;
+  sample_ip := '127.0.0.1';
+begin
+  
+  v_journal_id := workflow_case.begin_task_action(sample_task_id, 'start', 
+    sample_ip, sample_user_id, NULL);
+  workflow_case.end_task_action(v_journal_id, 'start', sample_task_id);
+
+  v_journal_id := workflow_case.begin_task_action(sample_task_id, 'finish', 
+    sample_ip, sample_user_id, 'Authoring complete');
+  workflow_case.set_attribute_value(v_journal_id, 'next_place', 'edited');
+  workflow_case.end_task_action(v_journal_id, 'finish', sample_task_id);
+
+end;
+/
+

Note the distinction between approval or rejection is determined +solely by the value of the next_place attribute.


karlg@arsdigita.com
+Last Modified: $Id: workflow.html,v 1.1.1.1 2001/03/13 22:59:26 +ben Exp $ +