web/views/navigation.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Wed, 28 Apr 2010 12:15:52 +0200
brancholdstable
changeset 5424 8ecbcbff9777
parent 5421 8167de96c523
child 5556 9ab2b4c74baf
child 5615 cfa9a776d99a
permissions -rw-r--r--
replace logilab-common by CubicWeb in disclaimer
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
     1
# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
     2
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
     3
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
     4
# This file is part of CubicWeb.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
     5
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
     6
# CubicWeb is free software: you can redistribute it and/or modify it under the
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
     7
# terms of the GNU Lesser General Public License as published by the Free
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
     8
# Software Foundation, either version 2.1 of the License, or (at your option)
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
     9
# any later version.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
    10
#
5424
8ecbcbff9777 replace logilab-common by CubicWeb in disclaimer
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5421
diff changeset
    11
# CubicWeb is distributed in the hope that it will be useful, but WITHOUT
5421
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
    12
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
    13
# FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
    14
# details.
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
    15
#
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
    16
# You should have received a copy of the GNU Lesser General Public License along
8167de96c523 proper licensing information (LGPL-2.1). Hope I get it right this time.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4721
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    18
"""navigation components definition for CubicWeb web client
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    20
"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    21
__docformat__ = "restructuredtext en"
2259
5d90bd26af8b cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    22
_ = unicode
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    23
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    24
from rql.nodes import VariableRef, Constant
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    25
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2259
diff changeset
    26
from logilab.mtconverter import xml_escape
2613
5e19c2bb370e R [all] logilab.common 0.44 provides only deprecated
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2381
diff changeset
    27
from logilab.common.deprecation import deprecated
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    28
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    29
from cubicweb.interfaces import IPrevNext
692
800592b8d39b replace deprecated cubicweb.common.selectors by its new module path (cubicweb.selectors)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 588
diff changeset
    30
from cubicweb.selectors import (paginated_rset, sorted_rset,
800592b8d39b replace deprecated cubicweb.common.selectors by its new module path (cubicweb.selectors)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 588
diff changeset
    31
                                primary_view, match_context_prop,
800592b8d39b replace deprecated cubicweb.common.selectors by its new module path (cubicweb.selectors)
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 588
diff changeset
    32
                                one_line_rset, implements)
4023
eae23c40627a drop common subpackage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3777
diff changeset
    33
from cubicweb.uilib import cut
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    34
from cubicweb.web.component import EntityVComponent, NavigationComponent
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    35
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    36
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    37
class PageNavigation(NavigationComponent):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    38
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    39
    def call(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    40
        """displays a resultset by page"""
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    41
        w = self.w
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3377
diff changeset
    42
        req = self._cw
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3377
diff changeset
    43
        rset = self.cw_rset
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    44
        page_size = self.page_size
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    45
        start = 0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    46
        blocklist = []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    47
        params = dict(req.form)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    48
        self.clean_params(params)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    49
        basepath = req.relative_path(includeparams=False)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    50
        while start < rset.rowcount:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    51
            stop = min(start + page_size - 1, rset.rowcount - 1)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    52
            blocklist.append(self.page_link(basepath, params, start, stop,
588
f37ee42cd0e9 permit override of display index on simple navigation
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 445
diff changeset
    53
                                            self.index_display(start, stop)))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    54
            start = stop + 1
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    55
        w(u'<div class="pagination">')
3014
62ce5a139b52 [page nav] previous/next page links should also consider url's base path
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
    56
        w(u'%s&#160;' % self.previous_link(basepath, params))
2996
866a2c135c33 B #345282 xhtml requires to use &#160; instead of &nbsp;
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2650
diff changeset
    57
        w(u'[&#160;%s&#160;]' % u'&#160;| '.join(blocklist))
3014
62ce5a139b52 [page nav] previous/next page links should also consider url's base path
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
    58
        w(u'&#160;%s' % self.next_link(basepath, params))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    59
        w(u'</div>')
1657
14e95f7aa033 delete-trailing-whitespaces, add page_size argument to .paginate
sylvain.thenault@logilab.fr
parents: 873
diff changeset
    60
588
f37ee42cd0e9 permit override of display index on simple navigation
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 445
diff changeset
    61
    def index_display(self, start, stop):
f37ee42cd0e9 permit override of display index on simple navigation
Arthur Lutz <arthur.lutz@logilab.fr>
parents: 445
diff changeset
    62
        return u'%s - %s' % (start+1, stop+1)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    63
2058
7ef12c03447c nicer vreg api, try to make rset an optional named argument in select and derivated (including selectors)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    64
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    65
class SortedNavigation(NavigationComponent):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    66
    """sorted navigation apply if navigation is needed (according to page size)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    67
    and if the result set is sorted
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    68
    """
742
99115e029dca replaced most of __selectors__ assignments with __select__
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 692
diff changeset
    69
    __select__ = paginated_rset() & sorted_rset()
1657
14e95f7aa033 delete-trailing-whitespaces, add page_size argument to .paginate
sylvain.thenault@logilab.fr
parents: 873
diff changeset
    70
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    71
    # number of considered chars to build page links
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    72
    nb_chars = 5
1657
14e95f7aa033 delete-trailing-whitespaces, add page_size argument to .paginate
sylvain.thenault@logilab.fr
parents: 873
diff changeset
    73
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    74
    def display_func(self, rset, col, attrname):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    75
        if attrname is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    76
            def index_display(row):
3751
ff404cef5244 take care to outer joins
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3689
diff changeset
    77
                if not rset[row][col]: # outer join
ff404cef5244 take care to outer joins
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3689
diff changeset
    78
                    return u''
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    79
                entity = rset.get_entity(row, col)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    80
                return entity.printable_value(attrname, format='text/plain')
4045
f4a52abb6f4f cw 3.6 api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4023
diff changeset
    81
        elif self._cw.vreg.schema.eschema(rset.description[0][col]).final:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    82
            def index_display(row):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    83
                return unicode(rset[row][col])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    84
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    85
            def index_display(row):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    86
                return rset.get_entity(row, col).view('text')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    87
        return index_display
1657
14e95f7aa033 delete-trailing-whitespaces, add page_size argument to .paginate
sylvain.thenault@logilab.fr
parents: 873
diff changeset
    88
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    89
    def call(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    90
        """displays links to navigate accross pages of a result set
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    91
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    92
        Displayed result is done according to a variable on which the sort
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    93
        is done, and looks like:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    94
        [ana - cro] | [cro - ghe] | ... | [tim - zou]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    95
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    96
        w = self.w
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3377
diff changeset
    97
        rset = self.cw_rset
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    98
        page_size = self.page_size
4045
f4a52abb6f4f cw 3.6 api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4023
diff changeset
    99
        rschema = self._cw.vreg.schema.rschema
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   100
        # attrname = the name of attribute according to which the sort
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   101
        # is done if any
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   102
        for sorterm in rset.syntax_tree().children[0].orderby:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   103
            if isinstance(sorterm.term, Constant):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   104
                col = sorterm.term.value - 1
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   105
                index_display = self.display_func(rset, col, None)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   106
                break
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   107
            var = sorterm.term.get_nodes(VariableRef)[0].variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   108
            col = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   109
            for ref in var.references():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   110
                rel = ref.relation()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   111
                if rel is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   112
                    continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   113
                attrname = rel.r_type
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   114
                if attrname == 'is':
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   115
                    continue
3689
deb13e88e037 follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3018
diff changeset
   116
                if not rschema(attrname).final:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   117
                    col = var.selected_index()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   118
                    attrname = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   119
                if col is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   120
                    # final relation or not selected non final relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   121
                    if var is rel.children[0]:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   122
                        relvar = rel.children[1].children[0].get_nodes(VariableRef)[0]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   123
                    else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   124
                        relvar = rel.children[0].variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   125
                    col = relvar.selected_index()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   126
                if col is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   127
                    break
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   128
            else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   129
                # no relation but maybe usable anyway if selected
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   130
                col = var.selected_index()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   131
                attrname = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   132
            if col is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   133
                index_display = self.display_func(rset, col, attrname)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   134
                break
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   135
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   136
            # nothing usable found, use the first column
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   137
            index_display = self.display_func(rset, 0, None)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   138
        blocklist = []
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3377
diff changeset
   139
        params = dict(self._cw.form)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   140
        self.clean_params(params)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   141
        start = 0
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3377
diff changeset
   142
        basepath = self._cw.relative_path(includeparams=False)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   143
        while start < rset.rowcount:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   144
            stop = min(start + page_size - 1, rset.rowcount - 1)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   145
            cell = self.format_link_content(index_display(start), index_display(stop))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   146
            blocklist.append(self.page_link(basepath, params, start, stop, cell))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   147
            start = stop + 1
3014
62ce5a139b52 [page nav] previous/next page links should also consider url's base path
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   148
        self.write_links(basepath, params, blocklist)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   149
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   150
    def format_link_content(self, startstr, stopstr):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   151
        text = u'%s - %s' % (startstr.lower()[:self.nb_chars],
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   152
                             stopstr.lower()[:self.nb_chars])
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2259
diff changeset
   153
        return xml_escape(text)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   154
3014
62ce5a139b52 [page nav] previous/next page links should also consider url's base path
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   155
    def write_links(self, basepath, params, blocklist):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   156
        self.w(u'<div class="pagination">')
3014
62ce5a139b52 [page nav] previous/next page links should also consider url's base path
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   157
        self.w(u'%s&#160;' % self.previous_link(basepath, params))
2996
866a2c135c33 B #345282 xhtml requires to use &#160; instead of &nbsp;
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2650
diff changeset
   158
        self.w(u'[&#160;%s&#160;]' % u'&#160;| '.join(blocklist))
3014
62ce5a139b52 [page nav] previous/next page links should also consider url's base path
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2996
diff changeset
   159
        self.w(u'&#160;%s' % self.next_link(basepath, params))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   160
        self.w(u'</div>')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   161
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   162
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   163
class NextPrevNavigationComponent(EntityVComponent):
3377
dd9d292b6a6d use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3023
diff changeset
   164
    __regid__ = 'prevnext'
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   165
    # register msg not generated since no entity implements IPrevNext in cubicweb
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   166
    # itself
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   167
    title = _('contentnavigation_prevnext')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   168
    help = _('contentnavigation_prevnext_description')
742
99115e029dca replaced most of __selectors__ assignments with __select__
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 692
diff changeset
   169
    __select__ = (one_line_rset() & primary_view()
99115e029dca replaced most of __selectors__ assignments with __select__
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 692
diff changeset
   170
                  & match_context_prop() & implements(IPrevNext))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   171
    context = 'navbottom'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   172
    order = 10
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   173
    def call(self, view=None):
4721
8f63691ccb7f pylint style fixes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4719
diff changeset
   174
        entity = self.cw_rset.get_entity(0, 0)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   175
        previous = entity.previous_entity()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   176
        next = entity.next_entity()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   177
        if previous or next:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3377
diff changeset
   178
            textsize = self._cw.property_value('navigation.short-line-size')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   179
            self.w(u'<div class="prevnext">')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   180
            if previous:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   181
                self.w(u'<div class="previousEntity left">')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   182
                self.w(self.previous_link(previous, textsize))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   183
                self.w(u'</div>')
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3377
diff changeset
   184
                self._cw.html_headers.add_raw('<link rel="prev" href="%s" />'
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2259
diff changeset
   185
                                              % xml_escape(previous.absolute_url()))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   186
            if next:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   187
                self.w(u'<div class="nextEntity right">')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   188
                self.w(self.next_link(next, textsize))
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   189
                self.w(u'</div>')
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3377
diff changeset
   190
                self._cw.html_headers.add_raw('<link rel="next" href="%s" />'
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2259
diff changeset
   191
                                              % xml_escape(next.absolute_url()))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   192
            self.w(u'</div>')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   193
            self.w(u'<div class="clear"></div>')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   194
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   195
    def previous_link(self, previous, textsize):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   196
        return u'<a href="%s" title="%s">&lt;&lt; %s</a>' % (
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2259
diff changeset
   197
            xml_escape(previous.absolute_url()),
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3377
diff changeset
   198
            self._cw._('i18nprevnext_previous'),
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2259
diff changeset
   199
            xml_escape(cut(previous.dc_title(), textsize)))
1657
14e95f7aa033 delete-trailing-whitespaces, add page_size argument to .paginate
sylvain.thenault@logilab.fr
parents: 873
diff changeset
   200
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   201
    def next_link(self, next, textsize):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   202
        return u'<a href="%s" title="%s">%s &gt;&gt;</a>' % (
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2259
diff changeset
   203
            xml_escape(next.absolute_url()),
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3377
diff changeset
   204
            self._cw._('i18nprevnext_next'),
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2259
diff changeset
   205
            xml_escape(cut(next.dc_title(), textsize)))
4244
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   206
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   207
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   208
def do_paginate(view, rset=None, w=None, show_all_option=True, page_size=None):
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   209
    """write pages index in w stream (default to view.w) and then limit the result
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   210
    set (default to view.rset) to the currently displayed page
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   211
    """
4265
0912f111b028 3.6 api update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   212
    req = view._cw
4244
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   213
    if rset is None:
4265
0912f111b028 3.6 api update
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4252
diff changeset
   214
        rset = view.cw_rset
4357
ef8e20bfa287 case where 'w' argument is None should be handled in do_paginate
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4336
diff changeset
   215
    if w is None:
ef8e20bfa287 case where 'w' argument is None should be handled in do_paginate
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4336
diff changeset
   216
        w = view.w
4252
6c4f109c2b03 backport stable branch
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4072 4244
diff changeset
   217
    nav = req.vreg['components'].select_or_none(
4244
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   218
        'navigation', req, rset=rset, page_size=page_size)
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   219
    if nav:
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   220
        if w is None:
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   221
            w = view.w
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   222
        # get boundaries before component rendering
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   223
        start, stop = nav.page_boundaries()
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   224
        nav.render(w=w)
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   225
        params = dict(req.form)
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   226
        nav.clean_params(params)
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   227
        # make a link to see them all
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   228
        if show_all_option:
4382
6fb02edd05da 3.6 api update, cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4357
diff changeset
   229
            url = xml_escape(req.build_url(__force_display=1, **params))
4244
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   230
            w(u'<span><a href="%s">%s</a></span>\n'
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   231
              % (url, req._('show %s results') % len(rset)))
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   232
        rset.limit(offset=start, limit=stop-start, inplace=True)
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   233
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   234
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   235
def paginate(view, show_all_option=True, w=None, page_size=None, rset=None):
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   236
    """paginate results if the view is paginable and we're not explictly told to
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   237
    display everything (by setting __force_display in req.form)
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   238
    """
4336
45e5b8bd2f71 backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4335 4332
diff changeset
   239
    if view.paginable and not view._cw.form.get('__force_display'):
4357
ef8e20bfa287 case where 'w' argument is None should be handled in do_paginate
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4336
diff changeset
   240
        do_paginate(view, rset, w, show_all_option, page_size)
4244
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   241
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   242
# monkey patch base View class to add a .paginate([...])
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   243
# method to be called to write pages index in the view and then limit the result
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   244
# set to the current page
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   245
from cubicweb.view import View
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   246
View.do_paginate = do_paginate
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   247
View.paginate = paginate
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   248
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   249
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   250
#@deprecated (see below)
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   251
def limit_rset_using_paged_nav(self, req, rset, w, forcedisplay=False,
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   252
                               show_all_option=True, page_size=None):
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   253
    if not (forcedisplay or req.form.get('__force_display') is not None):
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   254
        do_paginate(self, rset, w, show_all_option, page_size)
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   255
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   256
View.pagination = deprecated('[3.2] .pagination is deprecated, use paginate')(
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   257
    limit_rset_using_paged_nav)
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   258
limit_rset_using_paged_nav = deprecated('[3.6] limit_rset_using_paged_nav is deprecated, use do_paginate')(
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4213
diff changeset
   259
    limit_rset_using_paged_nav)