No registered users in community rubick
in last 10 minutes
in last 10 minutes
Using List Builder
Using List Builder
List Builder (LB) was introduced in acs-templating 4.6.4, and it allows you to make tables very easily. It took me about two hours to convert a table of mine to LB, and the time is well worth it, because you don't have to manually put in all the code for sorting. It also seems very flexible.Plus, since you are benefiting from my learning process, you probably won't take two hours to learn it!
Example
The best example I've found is at the logger admin page. It uses list-builder well, and does nifty things with filters, etc..The basic idea
Walk with me as I convert my index.tcl and index.adp file to list-builder. This is the end of the .tcl file:The index.adp file looks something like this:# An HTML block for the breadcrumb trail set context_bar [ad_context_bar] set title "Organizations" db_multirow orgs orgs_query { }
You would then change the .tcl file to look like this:<master> <property name="title">@title@</property> <property name="context_bar">@context_bar@</property> <if @orgs:rowcount@ gt 0> <table cellpadding="3" cellspacing="0"> <tr> <th>Action <th>Name <th>Notes </if> <multiple name="orgs"> <tr> <td> <a href="one?organization_id=@orgs.organization_id@">Details</a> <if @write_p@> <a href="add-edit?organization_id=@orgs.organization_id@">Edit</a> </if> <if @delete_p@> <a href="delete?organization_id=@orgs.organization_id@">Delete</a> </if> </td> <td>@orgs.name@</td> <td>@orgs.notes@</td> ... </tr> </multiple> <if @orgs:rowcount@ gt 0> </table> </if> <if @create_p@> <ul> <li><a href="add-edit">Add an organization</a></p> </ul> </if>
Then you change the .adp file to look like this:template::list::create \ -name orgs \ -multirow orgs \ -key organization_id \ -elements { organization_id { } name { } notes { } } \ -main_class { narrow } db_multirow -extend { item_url } orgs orgs_query { } { set item_url [export_vars -base "one" {organization_id}] }
<master> <property name="title">@title@</property> <property name="context_bar">@context_bar@</property> <listtemplate name="orgs"></listtemplate>
Common errors
If you get an error like this:Then the problem is this:Too many positional parameters specified while executing "template::list::create__arg_parser" (procedure "template::list::create" line 1) invoked from within "template::list::create \ " ("uplevel" body line 86) invoked from within
This error means one of your arguments is being interpreted not as a named switch (-elements ...) but as a positional argument (no switch).This could easiliy be a line that doesn't have the \ at the end, or that has a space character after the \, or some other little typo like that.
Thanks, Lars!
Where the data comes from
From Alex Vorobiev:it is not clear from the docs, and may not be obvious, but the -multirow switch lets developer point to a db_multirow statement. in other words, one MUST create a db_multirow statement with a name that matches -multrow switch of the list-builder. the db_multirow statement, in turn, points to an sql query in the corresponding .xql file
db_multirow -to add url columns, use extend with export_vars -to get row number, use rownum; also see rowcount (in docs for the "multiple" template tag)
Adding in sorting
See adding in sorting From Alex Vorobiev:
for the default case, one must specify column name FOLLOWED by comma and sort order such as ASC or DESC
Several lines from the database in one list-builder cell?
OpenACS has a very cool <group> tag, which allows you to show several rows from the database in one row. For example, if you have the table foo, with columns x and y, with values ofx y --- 1 3 1 4 2 5You may want the output to look like:
1 3 4 2 5or close to that, using an HTML table. Well, the <group> tag does that. Can we do that with list-builder?
Well, quite easily, it turns out.
Just put something like this in the definition of your column (preferably the last one):
Unfortunately, this will mess up the alternating bands of light and dark, because the odd and even rows will not be valid.last_name { label "Who" display_template { <group column="item_id">@tasks.first_names@ @tasks.last_name@<br></group> } }
Formatting your table
If you want your table to be more compact, put this in:-main_class { narrow } \
Adding in action buttons on top
Add as part of your definition:If you put variables or functions in there, you'll notice they don't get substituted. So instead, you do this:-actions { "Use process" "process-use" "Use a process" "Task calendar" "my_url" "View task calendar" } \
Thanks, Dave.set actions [list "Use process" "process-use" "Use a process" "Task calendar" "my_url" "View task calendar"] -actions $actions \
Pagination
See pagination for list-builderFrom Alex Vorobiev:
-multirow vs -page_query it is not immediately clear from the docs, and may not be obvious, but when using pagination, both switches are necessary. the purpose of the -page_query is to fetch the ENTIRE result set, whereas the sql statement used by multirow would fetch only the current page set.
caching with current paginator (not jon griffin's new paginator) use "-page_flush_p 1" to prevent paginator from caching the page set and confusing the hell out of you (when newly added records are suddenly not appearing on the page)
Returning CSV files
If you'd like to return a comma-separated-value file, follow Lars' instructions on returning a CSV from list-builder. These CSV files are opened by Excel or other spreadsheet programs, and make an easy way of getting information out of the database for office workers.Getting list-builder to work on OpenACS 4.6.3
From Alex Vorobiev:Caroline Meeks adds:- copy acs-templating/tcl-list-procs.tcl and acs-templating/resources/lists from CVS/HEAD to the appropriate locations in 4.6.3 distribution - 4.6.3 does not support the new "noquote" tag; any such tags can be safely removed from templates in versions of openacs prior to 5.0
- you have to use list-procs.tcl version 1.3. - Restart the server, don't just watch the files.
Displaying hierarchies
Alex Vorobiev:[ any information below that mentions pagination refers to old "broken" paginator ] - basically not possible with the current implementation of list-builder, see http://openacs.org/forums/message-view?message_id=28810 - poor man's hierarchies: one can build db_multirow as a join that would fetch parent and children records in the same query, and then use <group column=group_key> tag to iterate over the records with the same "key" until the key changes (see "group" template tag docs). in this case, pagination is very hairy, especially with joins: -> group "key" has to be same as the -page_query "key", where "key" is the query column -> if multirow query and page_query use the same joins, then the page_where_clause will list the same "key" id multiple times: for instance, project_id in ('455','455','466') - notice 455 appears twice. this causes fewer rows (than page_size) to be displayed on a page. the solution is to change page_query - use table aliasing 'spm_projects j', the same as in the multirow query, but no joins. if we don't do table aliasing, then the order by will break (order by j.project_id)
Joins with identical column names in two or more tables tables
Alex Vorobiev:- pagination: add the aliased column name to -key: j.project_id - sorting: add the aliased column name to orderby statements in the orderby block - sorting by columns in more than one table (j.project_id p.proposal_id) breaks because both tables need to appear in the page_query, which in turn breaks # of records per page... i thought that wrapping the page_query select in a "select distinct" or select with a group by would yield, but both actually re-sort by the distinct or groupby column, so there is no way to preserve the sort order of the inner select statement... giving up for now until the new paginator is out which may make all of this a moot point.
Misc. issues
Documentation
- The best documentation is the api-doc documentation for template::list (since the openacs.org website is on a version of OpenACS before 5.0, it doesn't include documentation for list-builder. You'll need to look on your installation).
- Look in cvs.openacs.org to see examples of list-builder usage. Lars has added it in to bug-tracker, forums, and logger, so you can use them as examples. Project-manager (in /contrib) also uses list-builder.
- More documentation is available.