Forum OpenACS Q&A: Controlling paginator link output

Collapse
Posted by Sean Redmond on

I'm using list builder to create a paginated table of results, but I'm also using a virtual url handler for pretty urls and the two are coming into conflict.

The url is in the form /theme/1234, and theme.vuh translates that into one_theme?theme_id=1234. theme_id is then used in a filter:

-filters {
        theme_id {
            label "Theme"
            where_clause {opl.objectpackageid=:theme_id}
        }
    } 

This all works great for the first page of results, but the paginator links for other pages are then: /theme/1234?page=2&theme_id=1234, etc. Which then produces the error “You've supplied two values for 'theme_id'”

Is there anyway to control the format of these links? The ultimate would be links with prettier urls like /theme/1234/2 insead of /theme/1234?page=2 but I would settle for not doubling the value!

Collapse
Posted by Jeff Lu on
This is one dirty way to do it, do a custom check, where in if page > 1, then you DO NOT post the theme_id from your index.vuh to your page.
Mind pasting your index.vuh here?
Collapse
Posted by Sean Redmond on

It's pretty basic:

if { [regexp {^(.+)/theme/([0-9]+)$} [ad_conn url] match root theme_id] } {
    rp_form_put theme_id $theme_id
    rp_internal_redirect /www/research/luce/one-theme
}

Based on what you said I tried this:

if { [regexp {^(.+)/theme/([0-9]+)$} [ad_conn url] match root theme_id] } {
    if { [ns_set find [rp_getform] page] < 0 } {
	rp_form_put theme_id $theme_id
    }	
    rp_internal_redirect /www/research/luce/one-theme
}

Which works, thanks. At least it gets around the server error.

However, its the second-best solution since it totally contradicts the purpose of using a .vuh for prettified URLs. I figured that to have any control over it one would have to create a new list template with custom paginator output. However, having delved into acs-templating/resources/lists/table.adp, it's worse than that. The list template does not do any formatting, of the URL (the value, here, of @paginator_pages.url@:

<if \@paginator.current_page@ ne \@paginator_pages.page@>
    <if \@paginator_pages.page@ lt 10>&nbsp;&nbsp;</if><a 
    href="\@paginator_pages.url@" title="\@paginator_pages.context@">\@paginator_pages.page@</a>
</if>
The URLs are created as a property of the paginator in template::list::render (in acs-templating/tcl/list-procs.tcl), like so:
# Add URL to the pages
template::multirow -local extend paginator_pages url 

template::multirow -local foreach paginator_pages {
    set url [get_url -name $list_properties(name) -override [list [list page $page]]]
}

It hink the only thing to do is create an alternate template that reformats the URL after the fact. Something like:

<a 
    href="<% [munge_the_url \@paginator_pages.url@] %>"
    title="\@paginator_pages.context@">
        \@paginator_pages.page@
</a>
Collapse
Posted by Dave Bauer on
Sean,

You are adding theme_id as a URL parameter when you call rp_form_put.

What we need is a way to make the variable available to the form-builder and ad_page_contract without adding it as a query variable.

I think the idea in this other thread https://openacs.org/forums/message-view?message_id=281658 is what you need.