Index: openacs-4/packages/ams/www/doc/index.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/ams/www/doc/index.html,v diff -u -r1.1 -r1.2 --- openacs-4/packages/ams/www/doc/index.html 21 Oct 2004 01:56:36 -0000 1.1 +++ openacs-4/packages/ams/www/doc/index.html 22 Oct 2004 01:17:31 -0000 1.2 @@ -6,42 +6,118 @@ border: 1px solid #CCC; background-color: #EEE; padding: 10px; -} + font-size: 0.9em; +} +code { + background-color: #EEE; + font-size: 0.9em; + padding-top: 0.05em; + padding-bottom: 0.05em; + padding-left: 2em; + padding-right: 2em; +} + +

AMS (Attribute Management System)

-

First define the elements via tcl - this could be in a package init proc:

+ +

AMS lets developers (via tcl api) and site wide administrators (via the the ams admin UI) add attributes to acs_object. These attributes can be dynamically added at any time on a live system. AMS then helps you collect attribute information for these defined acs_objects via input forms and helps you present them to users via your website. Whenever AMS stores ams attribute information about an object it keeps track of changes made via the content repository. This way you can see who and when a user changed an object's attributes and are able to revert back to a previous state.

+ +

Defining an Attribute

+ +

Ams attributes can either be defined via the ams admin user interface or via the ams::attribute::new proc. Every ams_attribute has an ams_widget associated with it. ams_widgets define what type of information the attribute contains the information necessary to generate forms and save various funcationally different types of information. View the documentation for ams::attribute::new to see what types of widgets are available. In most cases using the ams::attribute::new proc will be too tedious to do, instead it would be a good idea to use the shorthand as defined in creating and ams_list. + +

AMS Lists

+ +

AMS stores attributes in ams_lists. These lists are an ordered collection of attributes and can be called upon a variety of ways. Ams_lists can be used to generate ad_forms, or return attribute information for use with your packages UI. The attributes associated with your acs_object can be returned as named variables in your calling environment, as an array or as a list via the ams::object::attribute::values proc.

+ +

To define an ams_list of the elements you use the ams::define_list. That procedure has extensive documentation about the nuances of defining an ams_list. For example, lets assume that you are developing a package called "contacts" with the object_type of "ct_contact" and you want to define a list to collect information about a contact. You might choose to run the following procedure in when your system restarts:

-ams::define_list list_name "pretty list name" package_key object_type { attributes }
+ams::define_list -package_key "contacts" \
+        -object_type "ct_contact" \
+        -list_name "contact_person" \
+        -pretty_name "The Fields used to Add/Edit a Contact Person" \
+        -attributes {
+                {first_names textbox {First Name(s)} {First Names} required}
+                {middle_names textbox {Middle Name(s)} {Middle Names}}
+                {last_name textbox {Last Name} {Last Names} required}
+                {email email {Email Address} {Email Addresses}}
+                {url url {Website} {Websites}}
+                {home_address address {Home Address} {Home Addresses}}
+                {home_phone telecom_number {Home Phone} {Home Phones}}
+                {gender radio {Gender} {Genders} {options {{Male} {Female}}}}
+        }
 
-

For example

+ +

This will create an ams_list, define any attributes that haven't previously been defined for the ct_contact object and order the list in the order the attributes are specified.

+ +

AMS and ad_form

+

You have two options when dealing with ams and ad_form. Shorthand and detailed.

+

Shorthand

+

Shorthands is a completely simple way of creating forms without many options. These forms must only contain attributes defined in an ams_list. The supplied object_id must already exist in the acs_object table. The shorthand procs is ams_form, which is simply a wrapper for ad_form. For example, to create and ad_form named "contact_person_ae" create a page contacts/www/contact-person-ae.tcl with the following content:

-ams::define_list contact_person_ae "The Fields used to Add/Edit a Contact Person" contacts ct_contact {
-        {first_names textbox {First Name(s)} {First Names} required}
-        {middle_names textbox {Middle Name(s)} {Middle Names}}
-        {last_name textbox {Last Name} {Last Names} required}
-        {email email {Email Address} {Email Addresses}}
-        {url url {Website} {Websites}}
-        {home_address address {Home Address} {Home Addresses}}
-        {organization_address address {Organization Address} {Organization Addresses}}
-    }
+ad_page_contract {
+} {
+        {ct_contact_id:integer,notnull}
+}
+set title "Contact Person Add/Edit"
+set context [list $title]
+
+ams_form -package_key "contacts" \
+         -object_type "ct_contact" \
+         -list_name "contact_person" \
+         -form_name "contact_person_ae" \
+         -object_id $ct_contact_id \
+         -return_url "./"
+
+ad_return_template
 
-

Then on a object-ae page you simply call:

+

The contacts/www/contact-person-ae.adp would contain

-ad_form -name form_name -form [ams::ad_form::elements package_key list_name]
+<master>
+<property name="title">@title@</property">
+<property name="context">@context@</property">
+
+<formtemplate id="contact_person_ae"></formtemplate">
 
-

and in the ad_form -edit_request block put

+

That's it. If this isn't flexible enough you can also go with the detailed method.

+ + +

Detailed

+

For many application the AMS and ad_form shorthand will be too simplistic. For those situations, you can use ams to interface with ad_form. You need to define ad_from -form elements like this:

-ams::object::attribute::values -names -varenv $object_id
+ad_form ... -form [ams::ad_form::elements -package_key "contacts" -object_type "ct_contact" -list_name "contact_person"] ...
 
-

(this returns the variables upvared, i.e. first_names could be returned with a value of "Matthew"... etc.

+

Note that this procedure returns an ad form appropriate element list. If you intending to define other elements you will need to ad_from -extend -name form_name -form ...

+

+

In the ad_form -edit_request block put

+
+ad_form ... -edit_request {
+        ams::object::attribute::values -vars -object_id $object_id
+    } ...
+
+

This returns the variables upvared into your page, i.e. the first_names attribute could be returned with a value of "Jane" and the last_name attribute with a value of "Doe"... etc. ad_from looks for all form elements and appropriately pre-fills the form with the given values.

-

in the -on_submit block you put in:

+

In the -on_submit block you enter the following:

-ams::ad_form::save -name form_name package_key list_name object_id
+ad_from ... -on_submit {
+        ams::ad_form::save \
+            -package_key "contacts" \
+            -object_type "ct_contact" \
+            -list_name "contact_person" \
+            -form_name "contact_person_ae" \
+            -object_id $ct_contact_id
+    }
 
-

This is how you interface with AMS... then to display attributes you can call ams::object::attribute::values to get the results back as upvared variables, as an array or as a list however you want. So, if on the contact index package you do, for example +

This is how you interface with AMS and ad_form. You may also specify other code in the -form -on_submit and -on_submit blocks.

+ +

AMS and your package's UI

+ +

THIS SECTION NEEDS LOTS OF WORK

+ +

to display attributes you can call ams::object::attribute::values to get the results back as upvared variables, as an array or as a list however you want. So, if on the contact index package you do, for example

 db_multirow -extend { first_names last_name email home_phone } get_contacts { select ct_contact_id from ct_contacts order by names } {
@@ -58,5 +134,19 @@
 

Anyways, that's how it integrates with other packages. I've made it pretty efficient and i think the integration is pretty straight forward. If you have any questions please feel free to ask. AMS takes care of ALL content repository stuff, so what AMS does is effectively make it easy to make ANY package use the content repository without a steep learning curve. I am continuing to develop AMS since it fits our institutional priorities right now, and i don't think contacts will be too much work once ams is working correctly. I am currently working on an ETP revision that uses AMS as the attribute store for all page attributes... this way pretty much all data on a system can be housed in AMS, and other package are then in charge of relational issues. I want to work on contacts, and hope to get to it as soon as this other stuff is done. My boss went on a 2 month study leave, so once this is done i'm completely in charge of my time.

+
+

AMS Lists

+

You specify permissions at list object instantiation time +by specifying the context id for the ams_list object however +you want, only admins of the list get to modify that list. this +is all done through the tcl api. If you want a list to belong +to only one object you can simply program your package to +specify list names that are the id's of the object you are using.

+ +

this way you are assured unique list names for that object_type +based on package_key.

+ +

if you want a standard template for an object type you can...

+