Forum OpenACS Improvement Proposals (TIPs): TIP #67: (Implemented) Tcl API for Content Repository

Request notifications


Add Tcl procedure API to content repository pl/sql functions.
Priority will be given to functions that do not exist in any current Tcl API. All procedures that exist in the content repository Tcl library will eventually exist in one content:: namespace.

Naming conventions will be:


The item and revision procedures will provide support for extended content types so they will be able to be used with any properly defined content type.

The procedures will make available as many content repository functions that exist in the pl/sql as possbile.

This proposal does not include content type definition procedures. That is part of a seprerate effort.

Wherever possible code from the contrib package "bcms" will be adapted to create the new APIs. This should allow existing BCMS applications to be migrated to the content repository native APIs.


Currently there is no consistent namespace convention used in the existing content repository procedures. Many functions of the content repository are not exposed in any Tcl procedure.
Adding a Tcl API makes development of content repository based applications easier. It also reduces the amount of database specific code that is needed to work with the content repository. This should reduce the learning curve of  using the content repository.

It has been shown through the contrib package "bcms" that a Tcl API for the content repository functions can ease development.

Added 2004-06-30

The API will mirror the pl/sql apis except in the case of procedures that GET or SET attributes of cr_item. The api to get an attribute or all attributes will be:

::content::item::get returns an array with all of these attributes.

::content::item::get::element --element returns the single named element as a string.

In addition there will be a ::content::item::update procedure that will allow updating of one or more attributes of a content item. These procedures will only work on the attributes of the cr_items table.

Posted by Jeff Davis on
approved for head (for 5.2 or later)...

the namespace content already exists though, and has the following elements (none of which have any real docs afaict but are mostly accessors for the shared namespace data):

It also defines some variables (item_id, item_url, template_url revision_id) in that namespace. So we should be careful not to make it too confusing (and it might be a good time to comment those functions just so they don't get lost in the shuffle).

Posted by Dave Bauer on

That's right. Those procedures are already there. I'll take a look at them along with the rest of the API and add documentation.

Posted by Andrew Grumet on
Per OCT discussion...

Creating a Tcl API is approved but the specific api, and the deprecation of any old procs that it supersedes, is not (i.e. is subject to code review etc).

Posted by Dave Bauer on
I committed the preliminary APIs to CVS HEAD under


in addition there are


Most of the API calls package_exec_plsql so there are very few queries. I did change content::revision::new to use the cr_revisionsi view so that has to build a query from the attributes.

which I don't think we really need. I think permissions can be handled with the permission:: tcl api and keywords should be replaces with the categories package.

Comments welcome!

Posted by Malte Sussdorff on
I think permissions can be handled with the permission:: tcl api and keywords should be replaces with the categories package.

I utterly agree.

Posted by Dave Bauer on
I made a mistake and misread the procedures. The arguments to -var_list on all the package_exec_plsql all need to be in another level of [list].

Sorry, all the procs are broken until I get that fixed.

Posted by Dave Bauer on
I checked in the updated code with the correct var_list parameters.
Posted by Randy O'Meara on
Yes, much better. I have verified that at least create_type and drop_type work. Does this API work with 5.1 also, or just HEAD?

Thank you, Dave.


Posted by Joel Aufrecht on
There is another paradigm for basic "get item" operations. Example:

Foo has the attributes item_id, name, title, and creation_user.

::foo::get returns an array with all of these attributes.

::foo::get::element --element returns the single named element as a string.

Posted by Dave Bauer on
Hi Joel,
So what is your preference. Should be hide all the content::item::get_live_revision, ::get_latest_revision etc ?

I am thinking the same way as you, that there should only be one ::get procedure.  I am thinking the same for setting the attributes of a contnet item. Right now there are several pl/sql procecedures to set the various attributes of a content item. I created a procedure called content::item::update to allow update of any content item attribute (execpt storage_type and tree_sortkey, I don't think it should be easy to change those.)

Another procedure that we might want to change is set_live_revision which has a side effect in that is also can set the publish_status. In a similar case the existing item::publish procedure also sets the live_revision, so I'd like to think about how that should work in practice.

Posted by Jun Yamog on
Hi Dave,

Yes I think we should relook at the api.  I don't think we should add a tcl api that only gets a single attribute.  It maybe that the CR tcl api is not one to one with CR plpgsql api.  As for bcms I tried to standardize in returning an array for single item, and multirow for many items.

You can look at the ctk core. new, get and update calls is able to handle additional properties for a sub type content type.  I still use array to return a single object, list of lists to inject or update attributes.  Just don't look at how its implemented, its still needs to be change :)  The idea is wrap things on an api that does new, get and update easy for end developers.

Posted by Randy O'Meara on

Some of the CR plsql procs that you made TCL-accessible with package_exec_plsql cannot be accessed in this manner because they are not defined as accessible procs via plsql define_function_args(). See the actual error message below. The first set I encountered were:

content::type::register_relation_type, and
For these two, I simply added the appropriate define_function_args() calls:
select define_function_args('content_type__register_relation_type','content_type,target_type,relation_tag,min_n,max_n');
select define_function_args('content_type__unregister_relation_type','content_type,target_type,relation_tag');
to content-type.sql. These changes solved this particular set of problems. There are probably additional instances of this problem.

BTW, I am using your CR TCL API (successfully) under 5.1 by simply including the TCL files you provided. I'm forced to develop on 5.1 due to an error recently introduced on HEAD (here) that breaks the role system I've devised which utilizes rel_types::new. I don't know who introduced the breakage, but I cannot develop on HEAD until the breakage is repaired.


Error generated before I added define_function_args:

ERROR:  Function content_type__register_relation_type() does not exist
    Unable to identify a function that satisfies the given argument types
    You may need to add explicit typecasts
    select content_type__register_relation_type()