Index: openacs-4/packages/acs-templating/tcl/acs-templating-init.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/tcl/acs-templating-init.tcl,v diff -u -r1.2.4.1 -r1.2.4.2 --- openacs-4/packages/acs-templating/tcl/acs-templating-init.tcl 29 Apr 2004 11:57:32 -0000 1.2.4.1 +++ openacs-4/packages/acs-templating/tcl/acs-templating-init.tcl 9 Dec 2004 03:48:57 -0000 1.2.4.2 @@ -86,7 +86,7 @@ # Default values for paginator properties variable defaults - set defaults [list pagesize 20 timeout 600 groupsize 10] + set defaults [list pagesize 20 timeout 600 groupsize 10 page_offset 0] } namespace eval data { Index: openacs-4/packages/acs-templating/tcl/list-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/tcl/list-procs.tcl,v diff -u -r1.18.2.7 -r1.18.2.8 --- openacs-4/packages/acs-templating/tcl/list-procs.tcl 29 Nov 2004 17:38:17 -0000 1.18.2.7 +++ openacs-4/packages/acs-templating/tcl/list-procs.tcl 9 Dec 2004 03:48:58 -0000 1.18.2.8 @@ -419,10 +419,6 @@ error "When specifying a non-zero page_size, you must also provide either page_query or page_query_name" } - if { [empty_string_p $list_properties(page_query_name)] } { - set list_properties(page_query_name) "--default-query-name-for-list-builder-paginators--" - } - # We create the selected page as a filter, so we get the filter,page thing out template::list::filter::create \ -list_name $name \ @@ -494,17 +490,40 @@ # Create the paginator if { ![empty_string_p $list_properties(page_size)] && $list_properties(page_size) != 0 } { - # We need to uplevel subst it so we get the filters evaluated - set list_properties(page_query_substed) [uplevel $list_properties(ulevel) [list subst -nobackslashes $list_properties(page_query)]] + if { [string equal $list_properties(page_query) ""] } { + # We need to uplevel db_map it to get the query from the right context + set list_properties(page_query_substed) \ + [uplevel $list_properties(ulevel) [list db_map $list_properties(page_query_name)]] + } else { + # We need to uplevel subst it so we get the filters evaluated + set list_properties(page_query_substed) \ + [uplevel $list_properties(ulevel) \ + [list subst -nobackslashes $list_properties(page_query)]] + } - # Generate a paginator name which includes all the fitler values, - # so the paginator cahing works properly + # Use some short variable names to make the expr readable + set page $list_properties(filter,page) + set groupsize $list_properties(page_groupsize) + set page_size $list_properties(page_size) + set page_group [expr ($page - 1 - (($page - 1) % $groupsize)) / $groupsize + 1] + set first_row [expr ($page_group - 1) * $groupsize * $page_size + 1] + set last_row [expr $first_row + ($groupsize + 1) * $page_size - 1] + set page_offset [expr ($page_group - 1) * $groupsize] + + # Now wrap the provided query with the limit information + set list_properties(page_query_substed) [db_map pagination_query] + + # Generate a paginator name which includes the page group we're in all the + # filter values, so the paginator cahing works properly set paginator_name $list_properties(name) + foreach filter $list_properties(filters) { if { ![string equal $filter "page"] && [info exists list_properties(filter,$filter)] } { append paginator_name ",$filter=$list_properties(filter,$filter)" } } + + append paginator_name ",page_group=$page_group" set list_properties(paginator_name) $paginator_name set flush_p f @@ -514,11 +533,12 @@ # We need this uplevel so that the bind variables in the query will get bound at the caller's level uplevel $ulevel [list template::paginator create \ - $list_properties(page_query_name) \ + --foo--bar-- \ $list_properties(paginator_name) \ $list_properties(page_query_substed) \ -pagesize $list_properties(page_size) \ -groupsize $list_properties(page_groupsize) \ + -page_offset $page_offset \ -flush_p $flush_p \ -contextual] @@ -705,10 +725,16 @@ return {} } + set ids [template::paginator get_row_ids $list_properties(paginator_name) $list_properties(filter,page)] + if { $tcl_list_p } { - return [template::paginator get_row_ids $list_properties(paginator_name) $list_properties(filter,page)] + return $ids } else { - return [template::paginator get_query $list_properties(paginator_name) $list_properties(key) $list_properties(filter,page)] + set quoted_ids [list] + foreach one_id $ids { + lappend quoted_ids "'[DoubleApos $one_id]'" + } + return [join $quoted_ids ","] } } Index: openacs-4/packages/acs-templating/tcl/paginator-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-templating/tcl/paginator-procs.tcl,v diff -u -r1.13 -r1.13.4.1 --- openacs-4/packages/acs-templating/tcl/paginator-procs.tcl 15 Oct 2003 12:35:51 -0000 1.13 +++ openacs-4/packages/acs-templating/tcl/paginator-procs.tcl 9 Dec 2004 03:48:58 -0000 1.13.4.1 @@ -43,6 +43,9 @@ list of rows in the query result and caches the result for subsequent queries. + @param statement_name A query name. This is overwritten by the contents of + the "query" parameter if it is not the empty string. + @param name A unique name corresponding to the query being paginated, including specific values in the where clause and sorting specified in the order by clause. @@ -70,6 +73,16 @@ letters of a title or date. By default, the second column in the result set returned by query will be used as the context. + + @option page_offset The first page in a set of page groups to be created by + this paginator. This can be used to slice very large sets of + page groups into paginators, cached separately (be sure to + name each page group's paginator uniquely if you're caching + pagination query results). Very useful since filling the cache + for an entire set of page groups can be very costly, and since + often only the first few pages of items (for instance, forum threads) + are visited through the pagination interface. The list builder + provides an example of how to do this. } { set level [template::adp_level] variable parse_level @@ -142,7 +155,7 @@ } set opts(row_count) [llength $opts(row_ids)] - set opts(page_count) [get_page $name $opts(row_count)] + set opts(page_count) [expr {[get_page $name $opts(row_count)] + $opts(page_offset)}] set opts(group_count) [get_group $name $opts(page_count)] } @@ -349,9 +362,10 @@ get_reference set pagesize $properties(pagesize) + set page_offset $properties(page_offset) # get the set of ids for the current page - set start [expr ($pagenum - 1) * $pagesize] + set start [expr ($pagenum - $page_offset - 1) * $pagesize] set end [expr $start + $pagesize - 1] set ids [lrange $properties(row_ids) $start $end] @@ -384,6 +398,7 @@ set group_count $properties(group_count) set group_size $properties(groupsize) + # set page_count [expr $properties(page_count) + $properties(page_offset)] set page_count $properties(page_count) if { $group > $group_count } { @@ -396,7 +411,7 @@ set start [expr ($group - 1) * $group_size + 1] set end [expr $start + $group_size] - if { $end > $page_count } { set end [expr $page_count] } + if { $end > $page_count } { set end $page_count } set pages [list]