Forum OpenACS Q&A: List builder, db_multirow -extend and <include>

I'm trying to use list builder to create a table that:

  1. In one column gives the id for a share (in a vegetable co-op of sorts, not that that's relevant) as a link to a view/edit page (i.e. one-share?share_id=...)
  2. In another column lists (in a <ul>) members associated with that share, with their names formatted as links to view/edit member pages.

#1 is easy to do:

    -elements {
        share_id {
            label "ID #"
            link_url_col item_url
            link_html "View"
        }
        ....

But I can't figure out #2. In my first try I joined the share and member tables and used <group>, but that doesn't really cut because it's a little too complex. It the following possible?:

  1. Query for just share_id
  2. In template::list::create, output share_id twice, but
    1. In the first column format it as a link (like #1 above)
    2. In the second column, format it as an <include>, that will take the share_id, then go off, run a query for the members, and format them as a list to be plugged into this cell

I can't figure out how to repeat a field in list builder and format it differently each time(though it's easy enough to repeat it in the query under different names), or how to use db_multirow -extend or anything else to format the output as an <include>. Any ideas would be greatly appreciated.

Collapse
Posted by Sean Redmond on

Alright, I found half my answer here. Use display_template. So this should be possible

template::list::create \
    -name shares \
    -multirow shares \
    -key share_id \
    -elements {
        id {
            label "Id"
        }
        id2 {
            display_template {
                <include src="share-member-list"
                share_id="@shares.id2@">
            }
        }
    }
    ....

But it doesn't work. If, instead of include, I use something like <span id="@shares.id2@"></span> I get the expected output, but with include:

can't read "__adp_stub": no such variable
    while executing
"template::util::url_to_file "share-member-list" "$__adp_stub""
    invoked from within
"if {[string equal "[ad_quotehtml [lang::util::localize ${shares:rowcount}]]" "0"]} {
append __adp_output "
    <tr class=\"list-odd last\">
      <td ..."
    ("uplevel" body line 39)
    invoked from within
"uplevel {

    variable ::template::parse_level
    lappend ::template::parse_level [info level]

    set __adp_output ""
append __adp_output "<table ..."
    ("eval" body line 1)
    invoked from within
"eval "uplevel {

    variable ::template::parse_level
    lappend ::template::parse_level \[info level\]

    $code

    template::util::lpop ::templa..."
    (procedure "template::adp_eval" line 4)
    invoked from within
"template::adp_eval __list_code"
    (procedure "template::list::render" line 77)
    invoked from within
"template::list::render -name "shares" -style """
    invoked from within
"append __adp_output "[template::list::render -name "shares" -style ""]""
    ("uplevel" body line 18)
    invoked from within
"uplevel {
    	  set __adp_output ""

    set __adp_master [template::util::url_to_file "[ad_parameter -package_id [ad_conn subsite_id] DefaultMaster ..."
    (procedure "template::code::adp::/var/lib/aolserver/ourcsa/packages/csa/..." line 2)
    invoked from within
"template::code::${template_extension}::$__adp_stub"
    (procedure "template::adp_parse" line 68)
    invoked from within
"template::adp_parse [file root [ad_conn file]] {}"
    (procedure "adp_parse_ad_conn_file" line 5)
    invoked from within
"$handler"
    ("uplevel" body line 2)
    invoked from within
"uplevel $code"
    invoked from within
"ad_try {
                $handler
            } ad_script_abort val {
                # do nothing
            }"
    invoked from within
"rp_serve_concrete_file [ad_conn file]"
    (procedure "rp_serve_abstract_file" line 60)
    invoked from within
"rp_serve_abstract_file "$root/$path""
    ("uplevel" body line 2)
    invoked from within
"uplevel $code"
    invoked from within
"ad_try {
            rp_serve_abstract_file "$root/$path"
            set tcl_url2file([ad_conn url]) [ad_conn file]
            set tcl_url2path_info..."

I know it's not a problem with the included file because it works if I include it normally, it only fails within template::list::create

Collapse
Posted by Jade Rubick on
Have you looked at my list-builder docs?

http://www.rubick.com/openacs

You can use the <group> tag

Jade, I have been using your list-builder and your (and Jon Griffin's) ad_form docs to get as far as I've gotten. Thanks for all that work!

In this case, I'm trying to get around using <group>, basically because it messes up the alternating row colors. Not a very big reason, but now the bee's in my bonnet. I've gotten this far:

template::list::create \
    -name shares \
    -multirow shares \
    -key share_id \
    -elements {
        share_id {
            label "ID #"
            link_url_col item_url
            link_html "View"
        }
    ....
        test {
            label "Test"
            display_template {
                @shares.test;noquote@
            }
        }
    } \
    -main_class { narrow }

db_multirow -extend { item_url test } shares get_shares {
} {
    set item_url [export_vars -base "one-share" {share_id}]
    set test "<include src=\"share-member-list\" share_id=\"$share_id\">"
}

So with db_multirow -extend, you add on a value that contains the HTML for the <include> and use disply_template to output it (with noquote). Done this way, the output is what you expect, but the <include> doesn't get processed (you can see the tag if you view the source). That would seem to imply that because of the order in which things are processed, there is no simple way to stick an <include> into template::list::create.

So what I probably have to do is store the HTML I would have wanted from the <include> in a variable within db_multirow. Ie.:

db_multirow -extend { item_url test } shares get_shares {
} {
    set item_url [export_vars -base "one-share" {share_id}]
    set test [make_me_a_list $share_id]
}

Where make_me_a_list would return the HTML for my desired <ul>.

Collapse
Posted by Jade Rubick on
Another problem with includes is that you're calling them once per line, which can be highly inefficient even if it works.

But if you find a solution that works better, please let me know. One possibility might be improving the list-builder template in acs-templating or wherever. It might be possible to fix the banding.

Collapse
Posted by Dave Bauer on
Sean,

your best bet is to generate a query that returns multiple rows for each grouping with the differece for each row being the member names.

Then you'll need to customize a listtemplate that will group on the share_id and only repeat the html for the names, so that you end up with one row. Alternatively just use the multiple and group tags which will be much easier in this case.

Is it possible to specify a different "style" in the listtemplate tag, similar to the formtemplate tag? It doesn't seem so, and I think I'm looking for a completely different behavior from list-builder.
Collapse
Posted by Jun Yamog on
Hi Sean,

style attribute on listtemplate tag eems to work on my openacs copy.