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.
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 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.
You have two options when dealing with ams and ad_form. Shorthand and detailed.
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.
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:
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_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 enter the following:
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 and ad_form. You may also specify other code in the -form -on_submit and -on_submit blocks.
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
ams::object::attribute::values -array "contact_info" -
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"