Forum OpenACS Q&A: Re: Very confused about CR
Exhibition is A) a content type.
Title and Description are attributes of the content type Exhibition.
To use the CR, you create your content_type which is basically the definition of your document and what fields/attributes it contains.
You create the content_type and all the attributes using pl/sql calls like so. Now this content_type serves as a outline/template from which you can create instances of your documents (in this case Exhibition documents).
All document instances have a single cr_item and at least one cr_revision associated with them. When you use content_item.set_live_revision( revision_id => :revision_id );
, with a revision_id, you basically tell the CR which cr_revision of your cr_item you wish to receive whenever the live/published cr_item is requested. This cr_revision is usually going to be the latest_revision saved. (Though if you are editing the cr_item via a GUI, the live_revision may not be the latest_revision but an earlier revision until the edited changes are posted as the live_revision. Or you might even revert your cr_item an earlier cr_revision to if you decide some edits were not so nice.)
For instance, in the press release example of the CR docs, you have a table cr_press_releases, for which you create an attribute, location, using content_type.create_attribute(). It sounds like the locations column would be added to cr_press_releases if it didn't already exist.
Yes.
Then what? There is no example of creating or updating a press release.
Sure there is. You create a Press Release or you create Exhibition documents=items by using the content_item.new API. This creates a cr_item and a first cr_revision for your document (=item. e.g. Press Release or Exhibit). You update the document/Press Release/Exhibit by Creating Content Revisions of your new cr_item (=document).
What's the content of the content type (I think it's the text of the release, which through some API not illustrated in the docs, you would save to cr_revisions.content)?
The content
attribute/field can be anything you want it to be! Usually, if you have a really simple document, the content may just be it's body and then that is all you have! Otherwise, you can use content to hold most of the meat of your document (for a given content_type) though one thing you get for free, is that the content attribute is automagically searchable via the default cr_revision FTS proc. So put something you want searchable in there. Or don't even use it all, make your own custom attributes (and optionally, your own FTS search procs for your content_type), you decide!
Can you just change the location in cr_press_releases? Does that create or require a new revision?
That does require a new revision. The CR creates a new revision any time anything in your document/cr_item is changed/updated. That's what revisions are for. Or, you can let the CR know to just update the live_revision in place and not ever create new revisions. You lose any auditing/tracking capabilities and the ability to revert to earlier revisions of your documents by doing this though.
a content type only has one versioned field, stored in cr_revisions.content (and/or possibly cr_revisions.lob, depending on whether it is text or binary?)
Kinda. By default a cr_revision gets a title, content and description. These are versioned. If you want to have more attributes for your custom content_type you must create them as generic storage or specific storage. I prefer specific storage because then I can create a table that holds the rest of the versioned fields for my content_type's cr_revisions.
What you add via content_type.create_attribute() is just a matter of convenience since it becomes part of your cr_content_typex view. You could safely ignore this step, but you'd be on your own for accessing the data.
Hmmm. If you ignore this step, you would not have any other attributes besides the default of content, title, description for your item and it's revisions. It becomes part of the view yes, because it's part of all revisions of your document/item then. There are views created for insert and viewing.
You have to write functions like your_content_type__new(), etc. to manage the creation of items and revisions
No. You can do it one of 3 ways. I like to do it the easiest way like this (straight from the docs):
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
);
Notice you pass the revision_id so you can either overwrite an existing revision or make use of the versioning and get a new revision.
For what it's worth, here's a basic step by step of how a content_type gets created and then you create documents (cr_items) and revisions from it.
Steps:
1) Define a content_type for document.
PERFORM content_type__create_type (
''your_exhibit'', -- content_type
''content_revision'', -- supertype
''Exhibit'', -- pretty_name
''Exhibits'', -- pretty_plural
''cr_your_exhibits'', -- table_name
''cr_revision_id'', -- id_column
NULL -- name_method
);
-- Uses inherited default content_revision__revision_name name_method if not specified.
-- When the content type is created, the CR creates a view called your_content_type_tablename_revisionsx (e.g. cr_orp_personal_adsx).
-- Note the x at the end of the name.
-- On postgres, a second view called your_content_type_revisionsi (e.g. orp_personal_adi) is also created.
-- The x view is created for selection, and the i view is created for inserts.
-- They join the acs_objects, cr_revisions, and your_content_type_items and your_content_type_revisions tables together.
-- Note that Personals pkg does not define a your_content_type_items table as all of the Personal Ads
-- columns/fields are version controlled and thus go in the cr_revisions and your_content_type_revisions tables.
2) Create a cr_item to create your first document/item of your new content_type
select content_item__new (:name::varchar,
:parent_id::int4,
:item_id::int4,
null,
now(),
:creation_user,
null,
:creation_ip,
:content_item,
:content_type,
null,
null,
'text/plain',
null,
null,
'text'::varchar)
3) Create a cr_revision for the cr_item/document/item
select content_revision__new (:title,
:description,
now(),
null,
null,
:data,
:item_id,
null,
now(),
:creation_user,
:creation_ip)
4) Insert into the "x" view for the content_type. This adds any/all custom fields you defined for your content_type to the revision you specify.
insert into cr_your_content_typex (
item_id, revision_id, title, height, width
) values (
18, 19, 'A Nice Drawing', 300, 400
);
BTW, I think the CMS docs are actually the best docs to look at for info on how the internals of the CR are designed to work. Then CR Dev Guide for more specifics on implementing once you have the understanding.
Tammy, thanks a lot. That helps immensely.