AMS (Attribute Management System)

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.

Widgets

The following procs associated with it in the tcl files, this is done via tcl so people can actually have a "widget" represent a series of widgets in ad_form or template::form

::widget::${widget}::ad_form_widget       - returns a string suitable for input into ad_form, it gets: attribute, pretty_name, value
::widget::${widget}::ad_form_save         - saves the input to an ad_form widget and returns a value_id
::widget::${widget}::ad_form_value        - returns a value suitable for input into ad_form, it gets, attribute, attribute_id and value
::widget::${widget}::template_form_widget - runs a proc suitable for template::form, it gets: pretty_name, attribute, attribute_id, value
::widget::${widget}::template_form_save   - saves the input to an termplate::form widget and returns a value_id
::widget::${widget}::template_form_value  - returns a value suitable for input into ad_form, it gets, attribute, attribute_id and value
::widget::${widget}::value_text           - return the value formatted for text output, value is provided - this in the future will allow for search indexing of this data
::widget::${widget}::value_html           - return the value formatted for html output, value is provided
::widget::${widget}::csv_value            - return the value formatted for csv output, value and attribute are provided
::widget::${widget}::csv_headers          - return the value formatted for csv output, attribute is provided, for example, if returning a postal address we would return ${attribute}__country and ${attribute}__city, etc. For something such as gender we would simply return ${attribute}
::widget::${widget}::csv_save             - save the value provided by csv, the input into this proc will be ${attribute}__subitem $value ${attribute}__subitem $value, its assumed that the cvs_headers will all be provided and that if there is no input a blank field will be supplied.



::widget::${widget}::datatypes

-- ams_widget_datatype_map is simplifies the selection of widgets to associate
-- with an attribute. This allows us to present an administrator with list of valid
-- widgets she can select for association with a particular datatype.

create table ams_widget_datatype_map (
        widget                  varchar(100)
                                constraint ams_widget_datatype_map_fk references ams_widgets(widget)
                                constraint ams_widget_datatype_map_nn not null,
        datatype                varchar(50)
                                constraint ams_widget_datatype_map_datatype_fk references acs_datatypes(datatype)
                                constraint ams_widget_datatype_map_datatype_nn not null
);


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 -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}}}}
        }

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:

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

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

<master>
<property name="title">@title@</property">
<property name="context">@context@</property">

<formtemplate id="contact_person_ae"></formtemplate">

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_form -form elements like this:

ad_form ... -form [ams::ad_form::elements -package_key "contacts" -object_type "ct_contact" -list_name "contact_person"] ...

Note that this procedure returns an ad form appropriate element list. If you intending to define other elements you will need to ad_form -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_form looks for all form elements and appropriately pre-fills the form with the given values.

In the -on_submit block you enter the following:

ad_form ... -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 and ad_form. You may also specify other code in the -form -on_submit and -on_submit blocks.

AMS and your package's UI

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-view page you do, for example to get an array with all attribute_values that are not null represented in.

ams::object::attribute::values -array "contact_info" -object_id $ct_contact_id

To add ams_attribute_values to a multirow you call ams::multirow::extend to efficiently extend your multirow with ams_attribute_values. For example:

db_multirow contacts get_contacts { select ct_contact_id from ct_contacts }

ams::multirow::extend \
    -package_key "contacts" \
    -object_type "ct_contact" \
    -list_name "contact_person" \
    -multirow "contacts" \
    -key "ct_contact_id"

AMS Permissions

THIS SECTION NEEDS TO BE PROGRAMMED AN DOCUMENTED