web/views/navigation.py
author Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
Wed, 21 Dec 2011 18:26:35 +0100
changeset 8139 f9ebb6d1abc3
parent 8110 d743865ba7ed
child 8190 2a3c1b787688
permissions -rw-r--r--
[server] use lgd.process_cursor to optimize processing of large resultsets update lgdb dependency to ensure we've a fix necessary for proper behaviour of the previous changeset
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7588
7588240bcb36 [i18n] fix undetected conflict
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7323
diff changeset
     1
# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
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
     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/>.
8057
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    18
"""This module provides some generic components to navigate in the web
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    19
application.
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    20
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    21
Pagination
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    22
----------
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    23
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    24
Several implementations for large result set pagination are provided:
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    25
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    26
.. autoclass:: PageNavigation
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    27
.. autoclass:: PageNavigationSelect
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    28
.. autoclass:: SortedNavigation
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    29
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    30
Pagination will appear when needed according to the `page-size` ui property.
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    31
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    32
This module monkey-patch the :func:`paginate` function to the base :class:`View`
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    33
class, so that you can ask pagination explicitly on every result-set based views.
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    34
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    35
.. autofunction:: paginate
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    36
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    37
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    38
Previous / next navigation
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    39
--------------------------
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    40
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    41
An adapter and its related component for the somewhat usal "previous / next"
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    42
navigation are provided.
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    43
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    44
  .. autoclass:: IPrevNextAdapter
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    45
  .. autoclass:: NextPrevNavigationComponent
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    46
"""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    47
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    48
__docformat__ = "restructuredtext en"
2259
5d90bd26af8b cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
    49
_ = unicode
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    50
8015
b9de628f90e6 [ui, pagination] when sorted in some date type, auto-set max characters (closes #2053038)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8009
diff changeset
    51
from datetime import datetime
b9de628f90e6 [ui, pagination] when sorted in some date type, auto-set max characters (closes #2053038)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8009
diff changeset
    52
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    53
from rql.nodes import VariableRef, Constant
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    54
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2259
diff changeset
    55
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
    56
from logilab.common.deprecation import deprecated
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    57
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
    58
from cubicweb.selectors import (paginated_rset, sorted_rset,
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    59
                                adaptable, implements)
4023
eae23c40627a drop common subpackage
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3777
diff changeset
    60
from cubicweb.uilib import cut
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    61
from cubicweb.view import EntityAdapter, implements_adapter_compat
6141
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
    62
from cubicweb.web.component import EmptyComponent, EntityCtxComponent, NavigationComponent
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    63
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    64
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    65
class PageNavigation(NavigationComponent):
8057
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    66
    """The default pagination component: display link to pages where each pages
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    67
    is identified by the item number of its first and last elements.
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    68
    """
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    69
    def call(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    70
        """displays a resultset by page"""
5615
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    71
        params = dict(self._cw.form)
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    72
        self.clean_params(params)
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    73
        basepath = self._cw.relative_path(includeparams=False)
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    74
        self.w(u'<div class="pagination">')
7323
53f38d39287f [nav component/cosmetics] have nice looking arrows insteads of << / >>
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6864
diff changeset
    75
        self.w(self.previous_link(basepath, params))
5615
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    76
        self.w(u'[&#160;%s&#160;]' %
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    77
               u'&#160;| '.join(self.iter_page_links(basepath, params)))
7323
53f38d39287f [nav component/cosmetics] have nice looking arrows insteads of << / >>
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6864
diff changeset
    78
        self.w(u'&#160;&#160;%s' % self.next_link(basepath, params))
5615
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    79
        self.w(u'</div>')
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    80
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    81
    def index_display(self, start, stop):
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    82
        return u'%s - %s' % (start+1, stop+1)
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    83
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    84
    def iter_page_links(self, basepath, params):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3377
diff changeset
    85
        rset = self.cw_rset
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    86
        page_size = self.page_size
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    87
        start = 0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    88
        while start < rset.rowcount:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    89
            stop = min(start + page_size - 1, rset.rowcount - 1)
5615
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    90
            yield self.page_link(basepath, params, start, stop,
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    91
                                 self.index_display(start, stop))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    92
            start = stop + 1
5615
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    93
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    94
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    95
class PageNavigationSelect(PageNavigation):
8057
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    96
    """This pagination component displays a result-set by page as
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    97
    :class:`PageNavigation` but in a <select>, which is better when there are a
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    98
    lot of results.
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
    99
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   100
    By default it will be selected when there are more than 4 pages to be
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   101
    displayed.
5615
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   102
    """
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   103
    __select__ = paginated_rset(4)
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   104
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   105
    page_link_templ = u'<option value="%s" title="%s">%s</option>'
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   106
    selected_page_link_templ = u'<option value="%s" selected="selected" title="%s">%s</option>'
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   107
    def call(self):
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   108
        params = dict(self._cw.form)
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   109
        self.clean_params(params)
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   110
        basepath = self._cw.relative_path(includeparams=False)
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   111
        w = self.w
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   112
        w(u'<div class="pagination">')
7323
53f38d39287f [nav component/cosmetics] have nice looking arrows insteads of << / >>
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6864
diff changeset
   113
        w(self.previous_link(basepath, params))
5615
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   114
        w(u'<select onchange="javascript: document.location=this.options[this.selectedIndex].value">')
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   115
        for option in self.iter_page_links(basepath, params):
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   116
            w(option)
cfa9a776d99a [navigation] when there are to much results, use a <select> based page navigation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   117
        w(u'</select>')
7323
53f38d39287f [nav component/cosmetics] have nice looking arrows insteads of << / >>
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 6864
diff changeset
   118
        w(u'&#160;&#160;%s' % self.next_link(basepath, params))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   119
        w(u'</div>')
1657
14e95f7aa033 delete-trailing-whitespaces, add page_size argument to .paginate
sylvain.thenault@logilab.fr
parents: 873
diff changeset
   120
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
   121
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   122
class SortedNavigation(NavigationComponent):
8057
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   123
    """This pagination component will be selected by default if there are less
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   124
    than 4 pages and if the result set is sorted.
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   125
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   126
    Displayed links to navigate accross pages of a result set are done according
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   127
    to the first variable on which the sort is done, and looks like:
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   128
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   129
        [ana - cro] | [cro - ghe] | ... | [tim - zou]
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   130
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   131
    You may want to override this component to customize display in some cases.
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   132
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   133
    .. automethod:: sort_on
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   134
    .. automethod:: display_func
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   135
    .. automethod:: format_link_content
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   136
    .. automethod:: write_links
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   137
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   138
    Below an example from the tracker cube:
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   139
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   140
    .. sourcecode:: python
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   141
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   142
      class TicketsNavigation(navigation.SortedNavigation):
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   143
          __select__ = (navigation.SortedNavigation.__select__
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   144
                        & ~paginated_rset(4) & is_instance('Ticket'))
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   145
          def sort_on(self):
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   146
              col, attrname = super(TicketsNavigation, self).sort_on()
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   147
              if col == 6:
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   148
                  # sort on state, we don't want that
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   149
                  return None, None
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   150
              return col, attrname
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   151
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   152
    The idea is that in trackers'ticket tables, result set is first ordered on
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   153
    ticket's state while this doesn't make any sense in the navigation. So we
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   154
    override :meth:`sort_on` so that if we detect such sorting, we disable the
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   155
    feature to go back to item number in the pagination.
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   156
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   157
    Also notice the `~paginated_rset(4)` in the selector so that if there are
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   158
    more than 4 pages to display, :class:`PageNavigationSelect` will still be
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   159
    selected.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   160
    """
742
99115e029dca replaced most of __selectors__ assignments with __select__
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 692
diff changeset
   161
    __select__ = paginated_rset() & sorted_rset()
1657
14e95f7aa033 delete-trailing-whitespaces, add page_size argument to .paginate
sylvain.thenault@logilab.fr
parents: 873
diff changeset
   162
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   163
    # number of considered chars to build page links
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   164
    nb_chars = 5
1657
14e95f7aa033 delete-trailing-whitespaces, add page_size argument to .paginate
sylvain.thenault@logilab.fr
parents: 873
diff changeset
   165
8057
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   166
    def call(self):
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   167
        # attrname = the name of attribute according to which the sort
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   168
        # is done if any
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   169
        col, attrname = self.sort_on()
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   170
        index_display = self.display_func(self.cw_rset, col, attrname)
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   171
        basepath = self._cw.relative_path(includeparams=False)
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   172
        params = dict(self._cw.form)
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   173
        self.clean_params(params)
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   174
        blocklist = []
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   175
        start = 0
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   176
        total = self.cw_rset.rowcount
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   177
        while start < total:
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   178
            stop = min(start + self.page_size - 1, total - 1)
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   179
            cell = self.format_link_content(index_display(start), index_display(stop))
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   180
            blocklist.append(self.page_link(basepath, params, start, stop, cell))
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   181
            start = stop + 1
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   182
        self.write_links(basepath, params, blocklist)
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   183
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   184
    def display_func(self, rset, col, attrname):
8057
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   185
        """Return a function that will be called with a row number as argument
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   186
        and should return a string to use as link for it.
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   187
        """
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   188
        if attrname is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   189
            def index_display(row):
3751
ff404cef5244 take care to outer joins
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3689
diff changeset
   190
                if not rset[row][col]: # outer join
ff404cef5244 take care to outer joins
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3689
diff changeset
   191
                    return u''
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   192
                entity = rset.get_entity(row, col)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   193
                return entity.printable_value(attrname, format='text/plain')
8057
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   194
        elif col is None: # smart links disabled.
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   195
            def index_display(row):
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   196
                return unicode(row)
4045
f4a52abb6f4f cw 3.6 api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4023
diff changeset
   197
        elif self._cw.vreg.schema.eschema(rset.description[0][col]).final:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   198
            def index_display(row):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   199
                return unicode(rset[row][col])
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   200
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   201
            def index_display(row):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   202
                return rset.get_entity(row, col).view('text')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   203
        return index_display
1657
14e95f7aa033 delete-trailing-whitespaces, add page_size argument to .paginate
sylvain.thenault@logilab.fr
parents: 873
diff changeset
   204
8057
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   205
    def sort_on(self):
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   206
        """Return entity column number / attr name to use for nice display by
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   207
        inspecting the rset'syntax tree.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   208
        """
4045
f4a52abb6f4f cw 3.6 api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 4023
diff changeset
   209
        rschema = self._cw.vreg.schema.rschema
8057
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   210
        for sorterm in self.cw_rset.syntax_tree().children[0].orderby:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   211
            if isinstance(sorterm.term, Constant):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   212
                col = sorterm.term.value - 1
8057
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   213
                return col, None
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   214
            var = sorterm.term.get_nodes(VariableRef)[0].variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   215
            col = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   216
            for ref in var.references():
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   217
                rel = ref.relation()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   218
                if rel is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   219
                    continue
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   220
                attrname = rel.r_type
5944
b962dff47c36 [ftirank] when ordered by fti rank, we don't want page navigation. Anyway, sorted nav component shouldn't consider has_text relation.
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5910
diff changeset
   221
                if attrname in ('is', 'has_text'):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   222
                    continue
3689
deb13e88e037 follow yams 0.25 api changes to improve performance
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3018
diff changeset
   223
                if not rschema(attrname).final:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   224
                    col = var.selected_index()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   225
                    attrname = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   226
                if col is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   227
                    # final relation or not selected non final relation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   228
                    if var is rel.children[0]:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   229
                        relvar = rel.children[1].children[0].get_nodes(VariableRef)[0]
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   230
                    else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   231
                        relvar = rel.children[0].variable
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   232
                    col = relvar.selected_index()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   233
                if col is not None:
8101
f9fa2f47572c [sorted navigation] refactor code so that when an attribute is found, nb_chars may be recomputed anyway according to variable type
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8057
diff changeset
   234
                    break
f9fa2f47572c [sorted navigation] refactor code so that when an attribute is found, nb_chars may be recomputed anyway according to variable type
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8057
diff changeset
   235
            else:
f9fa2f47572c [sorted navigation] refactor code so that when an attribute is found, nb_chars may be recomputed anyway according to variable type
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8057
diff changeset
   236
                # no relation but maybe usable anyway if selected
f9fa2f47572c [sorted navigation] refactor code so that when an attribute is found, nb_chars may be recomputed anyway according to variable type
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8057
diff changeset
   237
                col = var.selected_index()
f9fa2f47572c [sorted navigation] refactor code so that when an attribute is found, nb_chars may be recomputed anyway according to variable type
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8057
diff changeset
   238
                attrname = None
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   239
            if col is not None:
8015
b9de628f90e6 [ui, pagination] when sorted in some date type, auto-set max characters (closes #2053038)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8009
diff changeset
   240
                # if column type is date[time], set proper 'nb_chars'
b9de628f90e6 [ui, pagination] when sorted in some date type, auto-set max characters (closes #2053038)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8009
diff changeset
   241
                if var.stinfo['possibletypes'] & frozenset(('TZDatetime', 'Datetime',
b9de628f90e6 [ui, pagination] when sorted in some date type, auto-set max characters (closes #2053038)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8009
diff changeset
   242
                                                            'Date')):
b9de628f90e6 [ui, pagination] when sorted in some date type, auto-set max characters (closes #2053038)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8009
diff changeset
   243
                    self.nb_chars = len(self._cw.format_date(datetime.today()))
8057
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   244
                return col, attrname
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   245
        # nothing usable found, use the first column
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   246
        return 0, None
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   247
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   248
    def format_link_content(self, startstr, stopstr):
8057
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   249
        """Return text for a page link, where `startstr` and `stopstr` are the
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   250
        text for the lower/upper boundaries of the page.
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   251
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   252
        By default text are stripped down to :attr:`nb_chars` characters.
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   253
        """
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   254
        text = u'%s - %s' % (startstr.lower()[:self.nb_chars],
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   255
                             stopstr.lower()[:self.nb_chars])
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2259
diff changeset
   256
        return xml_escape(text)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   257
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
   258
    def write_links(self, basepath, params, blocklist):
8057
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   259
        """Return HTML for the whole navigation: `blocklist` is a list of HTML
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   260
        snippets for each page, `basepath` and `params` will be necessary to
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   261
        build previous/next links.
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   262
        """
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   263
        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
   264
        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
   265
        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
   266
        self.w(u'&#160;%s' % self.next_link(basepath, params))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   267
        self.w(u'</div>')
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   268
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   269
8057
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   270
def do_paginate(view, rset=None, w=None, show_all_option=True, page_size=None):
8102
619d41a4c770 [navigation] provide a link back from the full view to the paginated one
Julien Cristau <julien.cristau@logilab.fr>
parents: 8101
diff changeset
   271
    """write pages index in w stream (default to view.w) and then limit the
619d41a4c770 [navigation] provide a link back from the full view to the paginated one
Julien Cristau <julien.cristau@logilab.fr>
parents: 8101
diff changeset
   272
    result set (default to view.rset) to the currently displayed page if we're
619d41a4c770 [navigation] provide a link back from the full view to the paginated one
Julien Cristau <julien.cristau@logilab.fr>
parents: 8101
diff changeset
   273
    not explicitly told to display everything (by setting __force_display in
619d41a4c770 [navigation] provide a link back from the full view to the paginated one
Julien Cristau <julien.cristau@logilab.fr>
parents: 8101
diff changeset
   274
    req.form)
8057
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   275
    """
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   276
    req = view._cw
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   277
    if rset is None:
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   278
        rset = view.cw_rset
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   279
    if w is None:
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   280
        w = view.w
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   281
    nav = req.vreg['components'].select_or_none(
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   282
        'navigation', req, rset=rset, page_size=page_size, view=view)
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   283
    if nav:
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   284
        if w is None:
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   285
            w = view.w
8102
619d41a4c770 [navigation] provide a link back from the full view to the paginated one
Julien Cristau <julien.cristau@logilab.fr>
parents: 8101
diff changeset
   286
        if req.form.get('__force_display'):
619d41a4c770 [navigation] provide a link back from the full view to the paginated one
Julien Cristau <julien.cristau@logilab.fr>
parents: 8101
diff changeset
   287
            # allow to come back to the paginated view
619d41a4c770 [navigation] provide a link back from the full view to the paginated one
Julien Cristau <julien.cristau@logilab.fr>
parents: 8101
diff changeset
   288
            params = dict(req.form)
8057
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   289
            basepath = req.relative_path(includeparams=False)
8102
619d41a4c770 [navigation] provide a link back from the full view to the paginated one
Julien Cristau <julien.cristau@logilab.fr>
parents: 8101
diff changeset
   290
            del params['__force_display']
8057
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   291
            url = nav.page_url(basepath, params)
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   292
            w(u'<div class="displayAllLink"><a href="%s">%s</a></div>\n'
8110
d743865ba7ed Tweak message to clarify it gets the pagination back
Julien Cristau <julien.cristau@logilab.fr>
parents: 8102
diff changeset
   293
              % (xml_escape(url), req._('back to pagination (%s results)')
d743865ba7ed Tweak message to clarify it gets the pagination back
Julien Cristau <julien.cristau@logilab.fr>
parents: 8102
diff changeset
   294
                                  % nav.page_size))
8102
619d41a4c770 [navigation] provide a link back from the full view to the paginated one
Julien Cristau <julien.cristau@logilab.fr>
parents: 8101
diff changeset
   295
        else:
619d41a4c770 [navigation] provide a link back from the full view to the paginated one
Julien Cristau <julien.cristau@logilab.fr>
parents: 8101
diff changeset
   296
            # get boundaries before component rendering
619d41a4c770 [navigation] provide a link back from the full view to the paginated one
Julien Cristau <julien.cristau@logilab.fr>
parents: 8101
diff changeset
   297
            start, stop = nav.page_boundaries()
619d41a4c770 [navigation] provide a link back from the full view to the paginated one
Julien Cristau <julien.cristau@logilab.fr>
parents: 8101
diff changeset
   298
            nav.render(w=w)
619d41a4c770 [navigation] provide a link back from the full view to the paginated one
Julien Cristau <julien.cristau@logilab.fr>
parents: 8101
diff changeset
   299
            params = dict(req.form)
619d41a4c770 [navigation] provide a link back from the full view to the paginated one
Julien Cristau <julien.cristau@logilab.fr>
parents: 8101
diff changeset
   300
            nav.clean_params(params)
619d41a4c770 [navigation] provide a link back from the full view to the paginated one
Julien Cristau <julien.cristau@logilab.fr>
parents: 8101
diff changeset
   301
            # make a link to see them all
619d41a4c770 [navigation] provide a link back from the full view to the paginated one
Julien Cristau <julien.cristau@logilab.fr>
parents: 8101
diff changeset
   302
            if show_all_option:
619d41a4c770 [navigation] provide a link back from the full view to the paginated one
Julien Cristau <julien.cristau@logilab.fr>
parents: 8101
diff changeset
   303
                basepath = req.relative_path(includeparams=False)
619d41a4c770 [navigation] provide a link back from the full view to the paginated one
Julien Cristau <julien.cristau@logilab.fr>
parents: 8101
diff changeset
   304
                params['__force_display'] = 1
619d41a4c770 [navigation] provide a link back from the full view to the paginated one
Julien Cristau <julien.cristau@logilab.fr>
parents: 8101
diff changeset
   305
                params['__fromnavigation'] = 1
619d41a4c770 [navigation] provide a link back from the full view to the paginated one
Julien Cristau <julien.cristau@logilab.fr>
parents: 8101
diff changeset
   306
                url = nav.page_url(basepath, params)
619d41a4c770 [navigation] provide a link back from the full view to the paginated one
Julien Cristau <julien.cristau@logilab.fr>
parents: 8101
diff changeset
   307
                w(u'<div class="displayAllLink"><a href="%s">%s</a></div>\n'
619d41a4c770 [navigation] provide a link back from the full view to the paginated one
Julien Cristau <julien.cristau@logilab.fr>
parents: 8101
diff changeset
   308
                  % (xml_escape(url), req._('show %s results') % len(rset)))
619d41a4c770 [navigation] provide a link back from the full view to the paginated one
Julien Cristau <julien.cristau@logilab.fr>
parents: 8101
diff changeset
   309
            rset.limit(offset=start, limit=stop-start, inplace=True)
8057
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   310
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   311
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   312
def paginate(view, show_all_option=True, w=None, page_size=None, rset=None):
8102
619d41a4c770 [navigation] provide a link back from the full view to the paginated one
Julien Cristau <julien.cristau@logilab.fr>
parents: 8101
diff changeset
   313
    """paginate results if the view is paginable
8057
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   314
    """
8102
619d41a4c770 [navigation] provide a link back from the full view to the paginated one
Julien Cristau <julien.cristau@logilab.fr>
parents: 8101
diff changeset
   315
    if view.paginable:
8057
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   316
        do_paginate(view, rset, w, show_all_option, page_size)
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   317
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   318
# monkey patch base View class to add a .paginate([...])
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   319
# method to be called to write pages index in the view and then limit the result
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   320
# set to the current page
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   321
from cubicweb.view import View
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   322
View.do_paginate = do_paginate
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   323
View.paginate = paginate
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   324
View.handle_pagination = False
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   325
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   326
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   327
from cubicweb.interfaces import IPrevNext
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   328
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   329
class IPrevNextAdapter(EntityAdapter):
8057
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   330
    """Interface for entities which can be linked to a previous and/or next
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   331
    entity
8057
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   332
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   333
    .. automethod:: next_entity
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   334
    .. automethod:: previous_entity
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   335
    """
6864
ea95004494a2 [adapters] fix #1424467 caused by precedence of bw compat method while the adapter is concret for a given class
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6141
diff changeset
   336
    __needs_bw_compat__ = True
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   337
    __regid__ = 'IPrevNext'
5895
6a3f776292a5 [selectors] avoid spurious warning when using implements by design
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5819
diff changeset
   338
    __select__ = implements(IPrevNext, warn=False) # XXX for bw compat, else should be abstract
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   339
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   340
    @implements_adapter_compat('IPrevNext')
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   341
    def next_entity(self):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   342
        """return the 'next' entity"""
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   343
        raise NotImplementedError
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   344
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   345
    @implements_adapter_compat('IPrevNext')
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   346
    def previous_entity(self):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   347
        """return the 'previous' entity"""
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   348
        raise NotImplementedError
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   349
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
   350
6141
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   351
class NextPrevNavigationComponent(EntityCtxComponent):
8057
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   352
    """Entities adaptable to the 'IPrevNext' should have this component
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   353
    automatically displayed. You may want to override this component to have a
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   354
    different look and feel.
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   355
    """
0f128fd3cbc8 [navigation] extract method from SortedNavigation.call to ease overriding
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8054
diff changeset
   356
3377
dd9d292b6a6d use __regid__ instead of id on appobject classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3023
diff changeset
   357
    __regid__ = 'prevnext'
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   358
    # register msg not generated since no entity implements IPrevNext in cubicweb
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   359
    # itself
6141
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   360
    help = _('ctxcomponents_prevnext_description')
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   361
    __select__ = EntityCtxComponent.__select__ & adaptable('IPrevNext')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   362
    context = 'navbottom'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   363
    order = 10
5966
0677cfb28ad2 [iprevnext] implements cell_call to remove warning when displayed in the main content zone
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5944
diff changeset
   364
7766
a832677c0aa6 [views/navigation] use the proper icons instead of ascii art (closes #1624943)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7588
diff changeset
   365
    @property
a832677c0aa6 [views/navigation] use the proper icons instead of ascii art (closes #1624943)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7588
diff changeset
   366
    def prev_icon(self):
a832677c0aa6 [views/navigation] use the proper icons instead of ascii art (closes #1624943)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7588
diff changeset
   367
        return '<img src="%s"/>' % xml_escape(self._cw.data_url('go_prev.png'))
a832677c0aa6 [views/navigation] use the proper icons instead of ascii art (closes #1624943)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7588
diff changeset
   368
a832677c0aa6 [views/navigation] use the proper icons instead of ascii art (closes #1624943)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7588
diff changeset
   369
    @property
a832677c0aa6 [views/navigation] use the proper icons instead of ascii art (closes #1624943)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7588
diff changeset
   370
    def next_icon(self):
a832677c0aa6 [views/navigation] use the proper icons instead of ascii art (closes #1624943)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7588
diff changeset
   371
        return '<img src="%s"/>' % xml_escape(self._cw.data_url('go_next.png'))
a832677c0aa6 [views/navigation] use the proper icons instead of ascii art (closes #1624943)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7588
diff changeset
   372
6141
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   373
    def init_rendering(self):
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   374
        adapter = self.entity.cw_adapt_to('IPrevNext')
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   375
        self.previous = adapter.previous_entity()
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   376
        self.next = adapter.next_entity()
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   377
        if not (self.previous or self.next):
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   378
            raise EmptyComponent()
5966
0677cfb28ad2 [iprevnext] implements cell_call to remove warning when displayed in the main content zone
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5944
diff changeset
   379
6141
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   380
    def render_body(self, w):
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   381
        w(u'<div class="prevnext">')
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   382
        self.prevnext(w)
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   383
        w(u'</div>')
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   384
        w(u'<div class="clear"></div>')
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   385
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   386
    def prevnext(self, w):
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   387
        if self.previous:
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   388
            self.prevnext_entity(w, self.previous, 'prev')
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   389
        if self.next:
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   390
            self.prevnext_entity(w, self.next, 'next')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   391
6141
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   392
    def prevnext_entity(self, w, entity, type):
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   393
        textsize = self._cw.property_value('navigation.short-line-size')
7766
a832677c0aa6 [views/navigation] use the proper icons instead of ascii art (closes #1624943)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7588
diff changeset
   394
        content = xml_escape(cut(entity.dc_title(), textsize))
6141
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   395
        if type == 'prev':
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   396
            title = self._cw._('i18nprevnext_previous')
7766
a832677c0aa6 [views/navigation] use the proper icons instead of ascii art (closes #1624943)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7588
diff changeset
   397
            icon = self.prev_icon
6141
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   398
            cssclass = u'previousEntity left'
7766
a832677c0aa6 [views/navigation] use the proper icons instead of ascii art (closes #1624943)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7588
diff changeset
   399
            content = icon + content
6141
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   400
        else:
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   401
            title = self._cw._('i18nprevnext_next')
7766
a832677c0aa6 [views/navigation] use the proper icons instead of ascii art (closes #1624943)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7588
diff changeset
   402
            icon = self.next_icon
6141
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   403
            cssclass = u'nextEntity right'
7766
a832677c0aa6 [views/navigation] use the proper icons instead of ascii art (closes #1624943)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7588
diff changeset
   404
            content = content + '&#160;&#160;' + icon
6141
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   405
        self.prevnext_div(w, type, cssclass, entity.absolute_url(),
7766
a832677c0aa6 [views/navigation] use the proper icons instead of ascii art (closes #1624943)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 7588
diff changeset
   406
                          title, content)
1657
14e95f7aa033 delete-trailing-whitespaces, add page_size argument to .paginate
sylvain.thenault@logilab.fr
parents: 873
diff changeset
   407
6141
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   408
    def prevnext_div(self, w, type, cssclass, url, title, content):
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   409
        w(u'<div class="%s">' % cssclass)
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   410
        w(u'<a href="%s" title="%s">%s</a>' % (xml_escape(url),
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   411
                                               xml_escape(title),
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   412
                                               content))
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   413
        w(u'</div>')
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   414
        self._cw.html_headers.add_raw('<link rel="%s" href="%s" />' % (
b8287e54b528 [web api] unify 'contentnav' (VComponent) and 'boxes' registries as 'ctxcomponents' (CtxComponent)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6007
diff changeset
   415
              type, xml_escape(url)))