view.py
author Aurelien Campeas <aurelien.campeas@logilab.fr>
Fri, 26 Apr 2013 12:10:37 +0200
changeset 8941 7b26fe71404f
parent 8666 1dd655788ece
child 8976 aeb7d400ee92
permissions -rw-r--r--
drop xhtml content-type support (closes #2065651) * HTMLStream does not care about xml any more * reqquest.demote_to_html and .xhtml_browser are deprecated * web config: drop force-html-content-type option * adjust tests
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8174
diff changeset
     1
# copyright 2003-2012 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: 5389
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: 5389
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: 5389
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: 5389
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: 5389
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: 5389
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: 5389
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: 5389
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: 5389
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: 5389
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: 5389
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: 5389
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: 5389
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: 5389
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: 5389
diff changeset
    17
# with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
5528
5d1b2ae7d459 cleanup
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5424
diff changeset
    18
"""abstract views and templates classes for CubicWeb web client"""
0
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
__docformat__ = "restructuredtext en"
1999
b9a8f5995658 obsolete methods
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1985
diff changeset
    21
_ = unicode
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    22
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: 6769
diff changeset
    23
import types, new
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    24
from cStringIO import StringIO
4244
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
    25
from warnings import warn
7938
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
    26
from functools import partial
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    27
2613
5e19c2bb370e R [all] logilab.common 0.44 provides only deprecated
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 2558
diff changeset
    28
from logilab.common.deprecation import deprecated
8666
1dd655788ece make ui configurations selectable (closes #2406609)
Florent Cayré <florent.cayre@logilab.fr>
parents: 8425
diff changeset
    29
from logilab.common.registry import yes
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2217
diff changeset
    30
from logilab.mtconverter import xml_escape
4058
b3578583b57b properly escape arguments of user callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3973
diff changeset
    31
2644
100b81ba3a98 F [view] missing import
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2613
diff changeset
    32
from rql import nodes
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    33
1181
620ec8e6ae19 cleanup, various fix to get something working
sylvain.thenault@logilab.fr
parents: 1144
diff changeset
    34
from cubicweb import NotAnEntity
8190
2a3c1b787688 [vreg] move base registry implementation to logilab.common. Closes #1916014
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8174
diff changeset
    35
from cubicweb.predicates import non_final_entity, nonempty_rset, none_rset
2656
a93ae0f6c0ad R [base classes] only AppObject remaning, no more AppRsetObject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2644
diff changeset
    36
from cubicweb.appobject import AppObject
708
b4728112625f move utils from cw.common to cw
sylvain.thenault@logilab.fr
parents: 707
diff changeset
    37
from cubicweb.utils import UStringIO, HTMLStream
6044
9e48ebd5400c [view] use the new magic js object to generate javascript func call for auto reload user callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
    38
from cubicweb.uilib import domid, js
2217
3a8cee8f8778 explicit display_name import
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2207
diff changeset
    39
from cubicweb.schema import display_name
633
087e3f1e87c8 more selectors update
sylvain.thenault@logilab.fr
parents: 632
diff changeset
    40
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    41
# robots control
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    42
NOINDEX = u'<meta name="ROBOTS" content="NOINDEX" />'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    43
NOFOLLOW = u'<meta name="ROBOTS" content="NOFOLLOW" />'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    44
8941
7b26fe71404f drop xhtml content-type support (closes #2065651)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8666
diff changeset
    45
TRANSITIONAL_DOCTYPE_NOEXT = u'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">\n'
7b26fe71404f drop xhtml content-type support (closes #2065651)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8666
diff changeset
    46
TRANSITIONAL_DOCTYPE = TRANSITIONAL_DOCTYPE_NOEXT # bw compat
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    47
6769
d784d64f28d0 Backed out changeset 84b67ae41a0d: with this fix, some
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6761
diff changeset
    48
STRICT_DOCTYPE_NOEXT = u'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">\n'
8941
7b26fe71404f drop xhtml content-type support (closes #2065651)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8666
diff changeset
    49
STRICT_DOCTYPE = STRICT_DOCTYPE_NOEXT # bw compat
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    50
661
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
    51
# base view object ############################################################
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
    52
2656
a93ae0f6c0ad R [base classes] only AppObject remaning, no more AppRsetObject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2644
diff changeset
    53
class View(AppObject):
8419
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    54
    """This class is an abstraction of a view class, used as a base class for
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    55
    every renderable object such as views, templates and other user interface
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    56
    components.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    57
8419
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    58
    A `View` is instantiated to render a result set or part of a result
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    59
    set. `View` subclasses may be parametrized using the following class
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    60
    attributes:
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
    61
8419
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    62
    :py:attr:`templatable` indicates if the view may be embedded in a main
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    63
      template or if it has to be rendered standalone (i.e. pure XML views must
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    64
      not be embedded in the main template of HTML pages)
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    65
    :py:attr:`content_type` if the view is not templatable, it should set the
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    66
      `content_type` class attribute to the correct MIME type (text/xhtml being
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    67
      the default)
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    68
    :py:attr:`category` this attribute may be used in the interface to regroup
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    69
      related objects (view kinds) together
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    70
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    71
    :py:attr:`paginable`
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    72
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    73
    :py:attr:`binary`
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    74
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    75
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    76
    A view writes to its output stream thanks to its attribute `w` (the
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    77
    append method of an `UStreamIO`, except for binary views).
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    78
4702
d9e51820d0c2 fix docstring
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4459
diff changeset
    79
    At instantiation time, the standard `_cw`, and `cw_rset` attributes are
d9e51820d0c2 fix docstring
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4459
diff changeset
    80
    added and the `w` attribute will be set at rendering time to a write
d9e51820d0c2 fix docstring
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4459
diff changeset
    81
    function to use.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    82
    """
816
9cd49a910fce kill Template class and 'templates' registry
sylvain.thenault@logilab.fr
parents: 781
diff changeset
    83
    __registry__ = 'views'
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
    84
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    85
    templatable = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    86
    # content_type = 'application/xhtml+xml' # text/xhtml'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    87
    binary = False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    88
    add_to_breadcrumbs = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    89
    category = 'view'
7990
a673d1d9a738 [diet] drop pre 3.6 API compatibility (but attempt to keep data cmopatibility). Closes #2017916
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7959
diff changeset
    90
    paginable = True
4244
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
    91
1143
8d097defbf2c change the way selected/__init__ are used for AppRsetObject
sylvain.thenault@logilab.fr
parents: 1132
diff changeset
    92
    def __init__(self, req=None, rset=None, **kwargs):
2822
f26578339214 deprecate appobject.vreg and rename appobject instance attributes using cw_ prefix
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2819
diff changeset
    93
        super(View, self).__init__(req, rset=rset, **kwargs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    94
        self.w = None
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
    @property
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    97
    def content_type(self):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
    98
        return self._cw.html_content_type()
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
    99
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   100
    def set_stream(self, w=None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   101
        if self.w is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   102
            return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   103
        if w is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   104
            if self.binary:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   105
                self._stream = stream = StringIO()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   106
            else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   107
                self._stream = stream = UStringIO()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   108
            w = stream.write
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   109
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   110
            stream = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   111
        self.w = w
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   112
        return stream
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   113
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   114
    # main view interface #####################################################
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
   115
1723
30c3a713ab61 View.dispatch -> View.render
sylvain.thenault@logilab.fr
parents: 1511
diff changeset
   116
    def render(self, w=None, **context):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   117
        """called to render a view object for a result set.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   118
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   119
        This method is a dispatched to an actual method selected
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   120
        according to optional row and col parameters, which are locating
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   121
        a particular row or cell in the result set:
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
   122
1132
96752791c2b6 pylint cleanup
sylvain.thenault@logilab.fr
parents: 986
diff changeset
   123
        * if row is specified, `cell_call` is called
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   124
        * if none of them is supplied, the view is considered to apply on
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   125
          the whole result set (which may be None in this case), `call` is
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   126
          called
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   127
        """
6922
cb1dd14a768f [view] fix/enhance view.render
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6909
diff changeset
   128
        # XXX use .cw_row/.cw_col
1132
96752791c2b6 pylint cleanup
sylvain.thenault@logilab.fr
parents: 986
diff changeset
   129
        row = context.get('row')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   130
        if row is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   131
            context.setdefault('col', 0)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   132
            view_func = self.cell_call
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   133
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   134
            view_func = self.call
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   135
        stream = self.set_stream(w)
6563
33343d6eae0a [view] log error on view_func call
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6458
diff changeset
   136
        try:
33343d6eae0a [view] log error on view_func call
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6458
diff changeset
   137
            view_func(**context)
7815
2a164a9cf81c [exceptions] stop catching any exception in various places (closes #1942716)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7670
diff changeset
   138
        except Exception:
6563
33343d6eae0a [view] log error on view_func call
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6458
diff changeset
   139
            self.debug('view call %s failed (context=%s)', view_func, context)
33343d6eae0a [view] log error on view_func call
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6458
diff changeset
   140
            raise
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   141
        # return stream content if we have created it
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   142
        if stream is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   143
            return self._stream.getvalue()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   144
2795
59965167bef3 move tal_render to View
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2788
diff changeset
   145
    def tal_render(self, template, variables):
59965167bef3 move tal_render to View
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2788
diff changeset
   146
        """render a precompiled page template with variables in the given
59965167bef3 move tal_render to View
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2788
diff changeset
   147
        dictionary as context
59965167bef3 move tal_render to View
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2788
diff changeset
   148
        """
59965167bef3 move tal_render to View
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2788
diff changeset
   149
        from cubicweb.ext.tal import CubicWebContext
59965167bef3 move tal_render to View
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2788
diff changeset
   150
        context = CubicWebContext()
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   151
        context.update({'self': self, 'rset': self.cw_rset, '_' : self._cw._,
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   152
                        'req': self._cw, 'user': self._cw.user})
2795
59965167bef3 move tal_render to View
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2788
diff changeset
   153
        context.update(variables)
59965167bef3 move tal_render to View
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2788
diff changeset
   154
        output = UStringIO()
59965167bef3 move tal_render to View
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2788
diff changeset
   155
        template.expand(context, output)
59965167bef3 move tal_render to View
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2788
diff changeset
   156
        return output.getvalue()
59965167bef3 move tal_render to View
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2788
diff changeset
   157
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   158
    # should default .call() method add a <div classs="section"> around each
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   159
    # rset item
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   160
    add_div_section = True
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
   161
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   162
    def call(self, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   163
        """the view is called for an entire result set, by default loop
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   164
        other rows of the result set and call the same view on the
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   165
        particular row
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   166
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   167
        Views applicable on None result sets have to override this method
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   168
        """
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   169
        rset = self.cw_rset
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   170
        if rset is None:
8204
332596be995e [view] fix error messages of NotImplementedError
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8174
diff changeset
   171
            raise NotImplementedError("%r an rset is required" % self)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   172
        wrap = self.templatable and len(rset) > 1 and self.add_div_section
6922
cb1dd14a768f [view] fix/enhance view.render
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6909
diff changeset
   173
        # avoid re-selection if rset of size 1, we already have the most
cb1dd14a768f [view] fix/enhance view.render
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6909
diff changeset
   174
        # specific view
cb1dd14a768f [view] fix/enhance view.render
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6909
diff changeset
   175
        if rset.rowcount != 1:
cb1dd14a768f [view] fix/enhance view.render
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6909
diff changeset
   176
            kwargs.setdefault('initargs', self.cw_extra_kwargs)
cb1dd14a768f [view] fix/enhance view.render
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6909
diff changeset
   177
            for i in xrange(len(rset)):
cb1dd14a768f [view] fix/enhance view.render
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6909
diff changeset
   178
                if wrap:
cb1dd14a768f [view] fix/enhance view.render
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6909
diff changeset
   179
                    self.w(u'<div class="section">')
cb1dd14a768f [view] fix/enhance view.render
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6909
diff changeset
   180
                self.wview(self.__regid__, rset, row=i, **kwargs)
cb1dd14a768f [view] fix/enhance view.render
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6909
diff changeset
   181
                if wrap:
cb1dd14a768f [view] fix/enhance view.render
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6909
diff changeset
   182
                    self.w(u"</div>")
cb1dd14a768f [view] fix/enhance view.render
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6909
diff changeset
   183
        else:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   184
            if wrap:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   185
                self.w(u'<div class="section">')
6922
cb1dd14a768f [view] fix/enhance view.render
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6909
diff changeset
   186
            kwargs.setdefault('col', 0)
cb1dd14a768f [view] fix/enhance view.render
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6909
diff changeset
   187
            self.cell_call(row=0, **kwargs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   188
            if wrap:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   189
                self.w(u"</div>")
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   190
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   191
    def cell_call(self, row, col, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   192
        """the view is called for a particular result set cell"""
8204
332596be995e [view] fix error messages of NotImplementedError
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8174
diff changeset
   193
        raise NotImplementedError(repr(self))
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
   194
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   195
    def linkable(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   196
        """return True if the view may be linked in a menu
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
   197
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   198
        by default views without title are not meant to be displayed
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   199
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   200
        if not getattr(self, 'title', None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   201
            return False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   202
        return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   203
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   204
    def is_primary(self):
4045
f4a52abb6f4f cw 3.6 api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 3998
diff changeset
   205
        return self.cw_extra_kwargs.get('is_primary', self.__regid__ == 'primary')
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
   206
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   207
    def url(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   208
        """return the url associated with this view. Should not be
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   209
        necessary for non linkable views, but a default implementation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   210
        is provided anyway.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   211
        """
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   212
        rset = self.cw_rset
2468
93853b6f3bad move all view.url() logic in a single implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2418
diff changeset
   213
        if rset is None:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   214
            return self._cw.build_url('view', vid=self.__regid__)
2468
93853b6f3bad move all view.url() logic in a single implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2418
diff changeset
   215
        coltypes = rset.column_types(0)
93853b6f3bad move all view.url() logic in a single implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2418
diff changeset
   216
        if len(coltypes) == 1:
93853b6f3bad move all view.url() logic in a single implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2418
diff changeset
   217
            etype = iter(coltypes).next()
4045
f4a52abb6f4f cw 3.6 api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 3998
diff changeset
   218
            if not self._cw.vreg.schema.eschema(etype).final:
2468
93853b6f3bad move all view.url() logic in a single implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2418
diff changeset
   219
                if len(rset) == 1:
93853b6f3bad move all view.url() logic in a single implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2418
diff changeset
   220
                    entity = rset.get_entity(0, 0)
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   221
                    return entity.absolute_url(vid=self.__regid__)
2468
93853b6f3bad move all view.url() logic in a single implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2418
diff changeset
   222
            # don't want to generate /<etype> url if there is some restriction
93853b6f3bad move all view.url() logic in a single implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2418
diff changeset
   223
            # on something else than the entity type
93853b6f3bad move all view.url() logic in a single implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2418
diff changeset
   224
            restr = rset.syntax_tree().children[0].where
93853b6f3bad move all view.url() logic in a single implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2418
diff changeset
   225
            # XXX norestriction is not correct here. For instance, in cases like
93853b6f3bad move all view.url() logic in a single implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2418
diff changeset
   226
            # "Any P,N WHERE P is Project, P name N" norestriction should equal
93853b6f3bad move all view.url() logic in a single implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2418
diff changeset
   227
            # True
93853b6f3bad move all view.url() logic in a single implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2418
diff changeset
   228
            norestriction = (isinstance(restr, nodes.Relation) and
93853b6f3bad move all view.url() logic in a single implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2418
diff changeset
   229
                             restr.is_types_restriction())
93853b6f3bad move all view.url() logic in a single implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2418
diff changeset
   230
            if norestriction:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   231
                return self._cw.build_url(etype.lower(), vid=self.__regid__)
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   232
        return self._cw.build_url('view', rql=rset.printable_rql(), vid=self.__regid__)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   233
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   234
    def set_request_content_type(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   235
        """set the content type returned by this view"""
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   236
        self._cw.set_content_type(self.content_type)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   237
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   238
    # view utilities ##########################################################
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   239
1985
9c1db4e06095 move view method's logic on the registry, so it's easier to call it from outside an appobject. Also make rset argument optional
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1977
diff changeset
   240
    def wview(self, __vid, rset=None, __fallback_vid=None, **kwargs):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   241
        """shortcut to self.view method automatically passing self.w as argument
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   242
        """
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   243
        self._cw.view(__vid, rset, __fallback_vid, w=self.w, **kwargs)
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   244
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   245
    def whead(self, data):
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   246
        self._cw.html_headers.write(data)
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 wdata(self, data):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   249
        """simple helper that escapes `data` and writes into `self.w`"""
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2217
diff changeset
   250
        self.w(xml_escape(data))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   251
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   252
    def html_headers(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   253
        """return a list of html headers (eg something to be inserted between
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   254
        <head> and </head> of the returned page
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   255
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   256
        by default return a meta tag to disable robot indexation of the page
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   257
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   258
        return [NOINDEX]
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
   259
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   260
    def page_title(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   261
        """returns a title according to the result set - used for the
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   262
        title in the HTML header
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   263
        """
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   264
        vtitle = self._cw.form.get('vtitle')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   265
        if vtitle:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   266
            return self._cw._(vtitle)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   267
        # class defined title will only be used if the resulting title doesn't
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   268
        # seem clear enough
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   269
        vtitle = getattr(self, 'title', None) or u''
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   270
        if vtitle:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   271
            vtitle = self._cw._(vtitle)
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   272
        rset = self.cw_rset
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   273
        if rset and rset.rowcount:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   274
            if rset.rowcount == 1:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   275
                try:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   276
                    entity = rset.complete_entity(0, 0)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   277
                    # use long_title to get context information if any
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   278
                    clabel = entity.dc_long_title()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   279
                except NotAnEntity:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   280
                    clabel = display_name(self._cw, rset.description[0][0])
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   281
                    clabel = u'%s (%s)' % (clabel, vtitle)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   282
            else :
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   283
                etypes = rset.column_types(0)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   284
                if len(etypes) == 1:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   285
                    etype = iter(etypes).next()
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   286
                    clabel = display_name(self._cw, etype, 'plural')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   287
                else :
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   288
                    clabel = u'#[*] (%s)' % vtitle
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   289
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   290
            clabel = vtitle
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   291
        return u'%s (%s)' % (clabel, self._cw.property_value('ui.site-title'))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   292
6039
6e84db1b3e44 [view] deprecate create_url in favor of a cw_create_url class method on entity classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5725
diff changeset
   293
    @deprecated('[3.10] use vreg["etypes"].etype_class(etype).cw_create_url(req)')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   294
    def create_url(self, etype, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   295
        """ return the url of the entity creation form for a given entity type"""
6039
6e84db1b3e44 [view] deprecate create_url in favor of a cw_create_url class method on entity classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5725
diff changeset
   296
        return self._cw.vreg["etypes"].etype_class(etype).cw_create_url(
6e84db1b3e44 [view] deprecate create_url in favor of a cw_create_url class method on entity classes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5725
diff changeset
   297
            self._cw, **kwargs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   298
6038
5c5d819e8e93 small cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5725
diff changeset
   299
    def field(self, label, value, row=True, show_label=True, w=None, tr=True,
5c5d819e8e93 small cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5725
diff changeset
   300
              table=False):
3809
1b9b51ee543e [web ui] PrimaryView.render_attributes now uses a table
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 3782
diff changeset
   301
        """read-only field"""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   302
        if w is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   303
            w = self.w
3809
1b9b51ee543e [web ui] PrimaryView.render_attributes now uses a table
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 3782
diff changeset
   304
        if table:
1b9b51ee543e [web ui] PrimaryView.render_attributes now uses a table
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 3782
diff changeset
   305
            w(u'<tr class="entityfield">')
1b9b51ee543e [web ui] PrimaryView.render_attributes now uses a table
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 3782
diff changeset
   306
        else:
1b9b51ee543e [web ui] PrimaryView.render_attributes now uses a table
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 3782
diff changeset
   307
            w(u'<div class="entityfield">')
3326
e3089ceee1ea don't show label if no label given
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3010
diff changeset
   308
        if show_label and label:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   309
            if tr:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   310
                label = display_name(self._cw, label)
3809
1b9b51ee543e [web ui] PrimaryView.render_attributes now uses a table
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 3782
diff changeset
   311
            if table:
1b9b51ee543e [web ui] PrimaryView.render_attributes now uses a table
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 3782
diff changeset
   312
                w(u'<th>%s</th>' % label)
1b9b51ee543e [web ui] PrimaryView.render_attributes now uses a table
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 3782
diff changeset
   313
            else:
6909
b8171392de16 [view] missing class on label span
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6864
diff changeset
   314
                w(u'<span class="label">%s</span> ' % label)
3809
1b9b51ee543e [web ui] PrimaryView.render_attributes now uses a table
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 3782
diff changeset
   315
        if table:
3969
970a748684b5 when fields are displayed in a table and label should'nt be displayed, set colspan to 2 on the field value cell
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3839
diff changeset
   316
            if not (show_label and label):
970a748684b5 when fields are displayed in a table and label should'nt be displayed, set colspan to 2 on the field value cell
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3839
diff changeset
   317
                w(u'<td colspan="2">%s</td></tr>' % value)
970a748684b5 when fields are displayed in a table and label should'nt be displayed, set colspan to 2 on the field value cell
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3839
diff changeset
   318
            else:
970a748684b5 when fields are displayed in a table and label should'nt be displayed, set colspan to 2 on the field value cell
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 3839
diff changeset
   319
                w(u'<td>%s</td></tr>' % value)
3809
1b9b51ee543e [web ui] PrimaryView.render_attributes now uses a table
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 3782
diff changeset
   320
        else:
1b9b51ee543e [web ui] PrimaryView.render_attributes now uses a table
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 3782
diff changeset
   321
            w(u'<span>%s</span></div>' % value)
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   322
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   323
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
   324
640
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 635
diff changeset
   325
# concrete views base classes #################################################
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 635
diff changeset
   326
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 635
diff changeset
   327
class EntityView(View):
843
5676811ef760 cleanup
sylvain.thenault@logilab.fr
parents: 822
diff changeset
   328
    """base class for views applying on an entity (i.e. uniform result set)"""
781
323656dd85a9 fix import, use non_final_entity instead of implements('Any')
sylvain.thenault@logilab.fr
parents: 757
diff changeset
   329
    __select__ = non_final_entity()
7670
6397a9051f65 [boxes] closes #1832844: translate views category in possible views boxes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7346
diff changeset
   330
    category = _('entityview')
640
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 635
diff changeset
   331
5715
2c3e83817a8e [view] add a new entity_call method to entity view protocol, allowing some to work with not yet created entities. Also, start considering 'eid' form parameters where we only consider 'rql', so we can move on bloquing arbitrary rql inputs (more to do on this...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5679
diff changeset
   332
    def call(self, **kwargs):
2c3e83817a8e [view] add a new entity_call method to entity view protocol, allowing some to work with not yet created entities. Also, start considering 'eid' form parameters where we only consider 'rql', so we can move on bloquing arbitrary rql inputs (more to do on this...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5679
diff changeset
   333
        if self.cw_rset is None:
7833
f19e3203dff6 [view] fix TypeError when calling req.view('vid', entity=entity) (closes #1947474)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
   334
            # * cw_extra_kwargs is the place where extra selection arguments are
f19e3203dff6 [view] fix TypeError when calling req.view('vid', entity=entity) (closes #1947474)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
   335
            #   stored
f19e3203dff6 [view] fix TypeError when calling req.view('vid', entity=entity) (closes #1947474)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
   336
            # * when calling req.view('somevid', entity=entity), 'entity' ends
f19e3203dff6 [view] fix TypeError when calling req.view('vid', entity=entity) (closes #1947474)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
   337
            #   up in cw_extra_kwargs and kwargs
f19e3203dff6 [view] fix TypeError when calling req.view('vid', entity=entity) (closes #1947474)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
   338
            #
f19e3203dff6 [view] fix TypeError when calling req.view('vid', entity=entity) (closes #1947474)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
   339
            # handle that to avoid a TypeError with a sanity check
f19e3203dff6 [view] fix TypeError when calling req.view('vid', entity=entity) (closes #1947474)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
   340
            #
f19e3203dff6 [view] fix TypeError when calling req.view('vid', entity=entity) (closes #1947474)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
   341
            # Notice that could probably be avoided by handling entity_call in
f19e3203dff6 [view] fix TypeError when calling req.view('vid', entity=entity) (closes #1947474)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
   342
            # .render
f19e3203dff6 [view] fix TypeError when calling req.view('vid', entity=entity) (closes #1947474)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
   343
            entity = self.cw_extra_kwargs.pop('entity')
f19e3203dff6 [view] fix TypeError when calling req.view('vid', entity=entity) (closes #1947474)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
   344
            if 'entity' in kwargs:
f19e3203dff6 [view] fix TypeError when calling req.view('vid', entity=entity) (closes #1947474)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
   345
                assert kwargs.pop('entity') is entity
f19e3203dff6 [view] fix TypeError when calling req.view('vid', entity=entity) (closes #1947474)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
   346
            self.entity_call(entity, **kwargs)
5715
2c3e83817a8e [view] add a new entity_call method to entity view protocol, allowing some to work with not yet created entities. Also, start considering 'eid' form parameters where we only consider 'rql', so we can move on bloquing arbitrary rql inputs (more to do on this...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5679
diff changeset
   347
        else:
2c3e83817a8e [view] add a new entity_call method to entity view protocol, allowing some to work with not yet created entities. Also, start considering 'eid' form parameters where we only consider 'rql', so we can move on bloquing arbitrary rql inputs (more to do on this...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5679
diff changeset
   348
            super(EntityView, self).call(**kwargs)
2c3e83817a8e [view] add a new entity_call method to entity view protocol, allowing some to work with not yet created entities. Also, start considering 'eid' form parameters where we only consider 'rql', so we can move on bloquing arbitrary rql inputs (more to do on this...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5679
diff changeset
   349
2c3e83817a8e [view] add a new entity_call method to entity view protocol, allowing some to work with not yet created entities. Also, start considering 'eid' form parameters where we only consider 'rql', so we can move on bloquing arbitrary rql inputs (more to do on this...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5679
diff changeset
   350
    def cell_call(self, row, col, **kwargs):
2c3e83817a8e [view] add a new entity_call method to entity view protocol, allowing some to work with not yet created entities. Also, start considering 'eid' form parameters where we only consider 'rql', so we can move on bloquing arbitrary rql inputs (more to do on this...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5679
diff changeset
   351
        self.entity_call(self.cw_rset.get_entity(row, col), **kwargs)
2c3e83817a8e [view] add a new entity_call method to entity view protocol, allowing some to work with not yet created entities. Also, start considering 'eid' form parameters where we only consider 'rql', so we can move on bloquing arbitrary rql inputs (more to do on this...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5679
diff changeset
   352
2c3e83817a8e [view] add a new entity_call method to entity view protocol, allowing some to work with not yet created entities. Also, start considering 'eid' form parameters where we only consider 'rql', so we can move on bloquing arbitrary rql inputs (more to do on this...)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5679
diff changeset
   353
    def entity_call(self, entity, **kwargs):
8204
332596be995e [view] fix error messages of NotImplementedError
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8174
diff changeset
   354
        raise NotImplementedError('%r %r' % (self.__regid__, self.__class__))
640
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 635
diff changeset
   355
6926
2cda8f1b4fae cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6922
diff changeset
   356
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   357
class StartupView(View):
843
5676811ef760 cleanup
sylvain.thenault@logilab.fr
parents: 822
diff changeset
   358
    """base class for views which doesn't need a particular result set to be
5676811ef760 cleanup
sylvain.thenault@logilab.fr
parents: 822
diff changeset
   359
    displayed (so they can always be displayed !)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   360
    """
707
21a59b468f1a __selectors__ -> __select__
sylvain.thenault@logilab.fr
parents: 700
diff changeset
   361
    __select__ = none_rset()
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   362
7670
6397a9051f65 [boxes] closes #1832844: translate views category in possible views boxes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7346
diff changeset
   363
    category = _('startupview')
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   364
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   365
    def html_headers(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   366
        """return a list of html headers (eg something to be inserted between
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   367
        <head> and </head> of the returned page
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   368
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   369
        by default startup views are indexed
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   370
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   371
        return []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   372
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   373
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   374
class EntityStartupView(EntityView):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   375
    """base class for entity views which may also be applied to None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   376
    result set (usually a default rql is provided by the view class)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   377
    """
781
323656dd85a9 fix import, use non_final_entity instead of implements('Any')
sylvain.thenault@logilab.fr
parents: 757
diff changeset
   378
    __select__ = none_rset() | non_final_entity()
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
   379
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   380
    default_rql = None
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
   381
2418
8f06e4f02733 optional rset
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2312
diff changeset
   382
    def __init__(self, req, rset=None, **kwargs):
2890
fdcb8a2bb6eb fix __init__ parameters
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2822
diff changeset
   383
        super(EntityStartupView, self).__init__(req, rset=rset, **kwargs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   384
        if rset is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   385
            # this instance is not in the "entityview" category
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   386
            self.category = 'startupview'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   387
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   388
    def startup_rql(self):
873
3d9df99b0bfa cleanup
sylvain.thenault@logilab.fr
parents: 843
diff changeset
   389
        """return some rql to be executed if the result set is None"""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   390
        return self.default_rql
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
   391
8174
b3e87e6865ef [base views] make it easier to override EntityStartupView behaviour when the rset is empty; closes #2126364
Florent Cayré <florent.cayre@gmail.com>
parents: 8013
diff changeset
   392
    def no_entities(self, **kwargs):
b3e87e6865ef [base views] make it easier to override EntityStartupView behaviour when the rset is empty; closes #2126364
Florent Cayré <florent.cayre@gmail.com>
parents: 8013
diff changeset
   393
        """override to display something when no entities were found"""
b3e87e6865ef [base views] make it easier to override EntityStartupView behaviour when the rset is empty; closes #2126364
Florent Cayré <florent.cayre@gmail.com>
parents: 8013
diff changeset
   394
        pass
b3e87e6865ef [base views] make it easier to override EntityStartupView behaviour when the rset is empty; closes #2126364
Florent Cayré <florent.cayre@gmail.com>
parents: 8013
diff changeset
   395
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   396
    def call(self, **kwargs):
873
3d9df99b0bfa cleanup
sylvain.thenault@logilab.fr
parents: 843
diff changeset
   397
        """override call to execute rql returned by the .startup_rql method if
3d9df99b0bfa cleanup
sylvain.thenault@logilab.fr
parents: 843
diff changeset
   398
        necessary
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   399
        """
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   400
        rset = self.cw_rset
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   401
        if rset is None:
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   402
            rset = self.cw_rset = self._cw.execute(self.startup_rql())
8174
b3e87e6865ef [base views] make it easier to override EntityStartupView behaviour when the rset is empty; closes #2126364
Florent Cayré <florent.cayre@gmail.com>
parents: 8013
diff changeset
   403
        if rset:
b3e87e6865ef [base views] make it easier to override EntityStartupView behaviour when the rset is empty; closes #2126364
Florent Cayré <florent.cayre@gmail.com>
parents: 8013
diff changeset
   404
            for i in xrange(len(rset)):
b3e87e6865ef [base views] make it easier to override EntityStartupView behaviour when the rset is empty; closes #2126364
Florent Cayré <florent.cayre@gmail.com>
parents: 8013
diff changeset
   405
                self.wview(self.__regid__, rset, row=i, **kwargs)
b3e87e6865ef [base views] make it easier to override EntityStartupView behaviour when the rset is empty; closes #2126364
Florent Cayré <florent.cayre@gmail.com>
parents: 8013
diff changeset
   406
        else:
b3e87e6865ef [base views] make it easier to override EntityStartupView behaviour when the rset is empty; closes #2126364
Florent Cayré <florent.cayre@gmail.com>
parents: 8013
diff changeset
   407
            self.no_entities(**kwargs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   408
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
   409
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   410
class AnyRsetView(View):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   411
    """base class for views applying on any non empty result sets"""
707
21a59b468f1a __selectors__ -> __select__
sylvain.thenault@logilab.fr
parents: 700
diff changeset
   412
    __select__ = nonempty_rset()
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
   413
7670
6397a9051f65 [boxes] closes #1832844: translate views category in possible views boxes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7346
diff changeset
   414
    category = _('anyrsetview')
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
   415
2203
efdd3a9f9028 update to new rql get_description api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1999
diff changeset
   416
    def columns_labels(self, mainindex=0, tr=True):
7938
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   417
        """compute the label of the rset colums
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   418
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   419
        The logic is based on :meth:`~rql.stmts.Union.get_description`.
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   420
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   421
        :param mainindex: The index of the main variable. This is an hint to get
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   422
                          more accurate label for various situation
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   423
        :type mainindex:  int
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   424
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   425
        :param tr: Should the label be translated ?
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   426
        :type tr: boolean
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   427
        """
370
7e76f651314b fix rset xml view
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 369
diff changeset
   428
        if tr:
7938
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   429
            translate = partial(display_name, self._cw)
370
7e76f651314b fix rset xml view
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 369
diff changeset
   430
        else:
8011
23552e79316f [column labels] full display_name prototype compat
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7959
diff changeset
   431
            translate = lambda val, *args,**kwargs: val
2203
efdd3a9f9028 update to new rql get_description api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1999
diff changeset
   432
        # XXX [0] because of missing Union support
7938
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   433
        rql_syntax_tree = self.cw_rset.syntax_tree()
7959
32349eb5d89d [table view] fix bug introduced in 7938:80c6e2155c3d leading to not translated table headers
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7938
diff changeset
   434
        rqlstdescr = rql_syntax_tree.get_description(mainindex, translate)[0]
369
c8a6edc224bb new rsetxml view, reusing most code from csvexport view
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 361
diff changeset
   435
        labels = []
7346
c6d8c3ce4a3e [view] ability to define a column header through custom label_column_<colindex> method, useful for table view to customize a specific column without specifying others
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6931
diff changeset
   436
        for colidx, label in enumerate(rqlstdescr):
7938
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   437
            labels.append(self.column_label(colidx, label, translate))
369
c8a6edc224bb new rsetxml view, reusing most code from csvexport view
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 361
diff changeset
   438
        return labels
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
   439
7938
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   440
    def column_label(self, colidx, default, translate_func=None):
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   441
        """return the label of a specified columns index
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   442
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   443
        Overwrite me if you need to compute specific label.
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   444
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   445
        :param colidx: The index of the column the call computes a label for.
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   446
        :type colidx:  int
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   447
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   448
        :param default: Default value. If ``"Any"`` the default value will be
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   449
                        recomputed as coma separated list for all possible
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   450
                        etypes name.
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   451
        :type colidx:  string
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   452
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   453
        :param translate_func: A function used to translate name.
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   454
        :type colidx:  function
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   455
        """
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   456
        label = default
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   457
        if label == 'Any':
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   458
            etypes = self.cw_rset.column_types(colidx)
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   459
            if translate_func is not None:
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   460
                etypes = map(translate_func, etypes)
7959
32349eb5d89d [table view] fix bug introduced in 7938:80c6e2155c3d leading to not translated table headers
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7938
diff changeset
   461
            label = u','.join(etypes)
7938
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   462
        return label
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   463
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   464
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   465
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   466
# concrete template base classes ##############################################
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   467
816
9cd49a910fce kill Template class and 'templates' registry
sylvain.thenault@logilab.fr
parents: 781
diff changeset
   468
class MainTemplate(View):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   469
    """main template are primary access point to render a full HTML page.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   470
    There is usually at least a regular main template and a simple fallback
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   471
    one to display error if the first one failed
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   472
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   473
8941
7b26fe71404f drop xhtml content-type support (closes #2065651)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8666
diff changeset
   474
    doctype = STRICT_DOCTYPE
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   475
1424
0a440312913b set_stream simplification
sylvain.thenault@logilab.fr
parents: 1421
diff changeset
   476
    def set_stream(self, w=None):
0a440312913b set_stream simplification
sylvain.thenault@logilab.fr
parents: 1421
diff changeset
   477
        if self.w is not None:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   478
            return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   479
        if w is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   480
            if self.binary:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   481
                self._stream = stream = StringIO()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   482
            else:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   483
                self._stream = stream = HTMLStream(self._cw)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   484
            w = stream.write
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   485
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   486
            stream = None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   487
        self.w = w
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   488
        return stream
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   489
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   490
    def write_doctype(self, xmldecl=True):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   491
        assert isinstance(self._stream, HTMLStream)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   492
        self._stream.doctype = self.doctype
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   493
        if not xmldecl:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   494
            self._stream.xmldecl = u''
661
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   495
822
e3d8db01f3f5 test_views fixes
sylvain.thenault@logilab.fr
parents: 819
diff changeset
   496
    def linkable(self):
e3d8db01f3f5 test_views fixes
sylvain.thenault@logilab.fr
parents: 819
diff changeset
   497
        return False
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   498
661
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   499
# concrete component base classes #############################################
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   500
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   501
class ReloadableMixIn(object):
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   502
    """simple mixin for reloadable parts of UI"""
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   503
661
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   504
    def user_callback(self, cb, args, msg=None, nonify=False):
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   505
        """register the given user callback and return an url to call it ready to be
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   506
        inserted in html
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   507
        """
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   508
        self._cw.add_js('cubicweb.ajax.js')
661
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   509
        if nonify:
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   510
            _cb = cb
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   511
            def cb(*args):
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   512
                _cb(*args)
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   513
        cbname = self._cw.register_onetime_callback(cb, *args)
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2217
diff changeset
   514
        return self.build_js(cbname, xml_escape(msg or ''))
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   515
661
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   516
    def build_update_js_call(self, cbname, msg):
4059
f1da1a7ef29b backport stable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4045 4058
diff changeset
   517
        rql = self.cw_rset.printable_rql()
6044
9e48ebd5400c [view] use the new magic js object to generate javascript func call for auto reload user callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   518
        return "javascript: %s" % js.userCallbackThenUpdateUI(
9e48ebd5400c [view] use the new magic js object to generate javascript func call for auto reload user callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   519
            cbname, self.__regid__, rql, msg, self.__registry__, self.domid)
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   520
4062
d16b2927afe6 oops, bad indent
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4060
diff changeset
   521
    def build_reload_js_call(self, cbname, msg):
6044
9e48ebd5400c [view] use the new magic js object to generate javascript func call for auto reload user callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6038
diff changeset
   522
        return "javascript: %s" % js.userCallbackThenReloadPage(cbname, msg)
661
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   523
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   524
    build_js = build_update_js_call # expect updatable component by default
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   525
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   526
    @property
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   527
    def domid(self):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   528
        return domid(self.__regid__)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   529
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   530
    @deprecated('[3.10] use .domid property')
661
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   531
    def div_id(self):
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   532
        return self.domid
661
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   533
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   534
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   535
class Component(ReloadableMixIn, View):
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   536
    """base class for components"""
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   537
    __registry__ = 'components'
707
21a59b468f1a __selectors__ -> __select__
sylvain.thenault@logilab.fr
parents: 700
diff changeset
   538
    __select__ = yes()
661
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   539
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   540
    # XXX huummm, much probably useless (should be...)
3010
684a0c546774 [ui props] drop htmlclass as a persistent property, this is definitly useless/unusable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2656
diff changeset
   541
    htmlclass = 'mainRelated'
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   542
    @property
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   543
    def cssclass(self):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   544
        return '%s %s' % (self.htmlclass, domid(self.__regid__))
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   545
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   546
    # XXX should rely on ReloadableMixIn.domid
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   547
    @property
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   548
    def domid(self):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   549
        return '%sComponent' % domid(self.__regid__)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   550
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   551
    @deprecated('[3.10] use .cssclass property')
661
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   552
    def div_class(self):
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   553
        return self.cssclass
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5533
diff changeset
   554
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5533
diff changeset
   555
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5533
diff changeset
   556
class Adapter(AppObject):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5533
diff changeset
   557
    """base class for adapters"""
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5533
diff changeset
   558
    __registry__ = 'adapters'
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5533
diff changeset
   559
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5533
diff changeset
   560
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5533
diff changeset
   561
def implements_adapter_compat(iface):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5533
diff changeset
   562
    def _pre39_compat(func):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5533
diff changeset
   563
        def decorated(self, *args, **kwargs):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5533
diff changeset
   564
            entity = self.entity
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5533
diff changeset
   565
            if hasattr(entity, func.__name__):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5533
diff changeset
   566
                warn('[3.9] %s method is deprecated, define it on a custom '
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5533
diff changeset
   567
                     '%s for %s instead' % (func.__name__, iface,
8666
1dd655788ece make ui configurations selectable (closes #2406609)
Florent Cayré <florent.cayre@logilab.fr>
parents: 8425
diff changeset
   568
                                            entity.__class__),
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5533
diff changeset
   569
                     DeprecationWarning)
5571
5d024bf9424b [adapters compat] make implements_adapter_compat selector compatible with attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5556
diff changeset
   570
                member = getattr(entity, func.__name__)
5d024bf9424b [adapters compat] make implements_adapter_compat selector compatible with attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5556
diff changeset
   571
                if callable(member):
5d024bf9424b [adapters compat] make implements_adapter_compat selector compatible with attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5556
diff changeset
   572
                    return member(*args, **kwargs)
5d024bf9424b [adapters compat] make implements_adapter_compat selector compatible with attributes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5556
diff changeset
   573
                return member
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5533
diff changeset
   574
            return func(self, *args, **kwargs)
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: 6769
diff changeset
   575
        decorated.decorated = func
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5533
diff changeset
   576
        return decorated
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5533
diff changeset
   577
    return _pre39_compat
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: 6769
diff changeset
   578
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: 6769
diff changeset
   579
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: 6769
diff changeset
   580
def unwrap_adapter_compat(cls):
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: 6769
diff changeset
   581
    parent = cls.__bases__[0]
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: 6769
diff changeset
   582
    for member_name in dir(parent):
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: 6769
diff changeset
   583
        member = getattr(parent, member_name)
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: 6769
diff changeset
   584
        if isinstance(member, types.MethodType) and hasattr(member.im_func, 'decorated') and not member_name in cls.__dict__:
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: 6769
diff changeset
   585
            method = new.instancemethod(member.im_func.decorated, None, cls)
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: 6769
diff changeset
   586
            setattr(cls, member_name, method)
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: 6769
diff changeset
   587
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: 6769
diff changeset
   588
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: 6769
diff changeset
   589
class auto_unwrap_bw_compat(type):
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: 6769
diff changeset
   590
    def __new__(mcs, name, bases, classdict):
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: 6769
diff changeset
   591
        cls = type.__new__(mcs, name, bases, classdict)
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: 6769
diff changeset
   592
        if not classdict.get('__needs_bw_compat__'):
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: 6769
diff changeset
   593
            unwrap_adapter_compat(cls)
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: 6769
diff changeset
   594
        return cls
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: 6769
diff changeset
   595
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: 6769
diff changeset
   596
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: 6769
diff changeset
   597
class EntityAdapter(Adapter):
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: 6769
diff changeset
   598
    """base class for entity adapters (eg adapt an entity to an interface)"""
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: 6769
diff changeset
   599
    __metaclass__ = auto_unwrap_bw_compat
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: 6769
diff changeset
   600
    def __init__(self, _cw, **kwargs):
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: 6769
diff changeset
   601
        try:
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: 6769
diff changeset
   602
            self.entity = kwargs.pop('entity')
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: 6769
diff changeset
   603
        except KeyError:
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: 6769
diff changeset
   604
            self.entity = kwargs['rset'].get_entity(kwargs.get('row') or 0,
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: 6769
diff changeset
   605
                                                    kwargs.get('col') or 0)
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: 6769
diff changeset
   606
        Adapter.__init__(self, _cw, **kwargs)