cubicweb/view.py
author Laurent Peuch <cortex@worlddomination.be>
Thu, 19 Dec 2019 06:33:49 +0100
changeset 12831 b1ef9690f357
parent 12780 8caa109dfe94
child 12846 ba3cf6aaa695
permissions -rw-r--r--
[mypy] type __select__ everywhere
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
11767
432f87a63057 flake8 and all
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 11057
diff changeset
    20
10666
7f6b5f023884 [py3k] replace '_ = unicode' in global scope (closes #7589459)
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10609
diff changeset
    21
from cubicweb import _
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    22
12780
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
    23
import re
10211
59a77e8847bc [view] Use io.BytesIO as stream for binary views
Rémi Cardona <remi.cardona@free.fr>
parents: 10068
diff changeset
    24
from io import BytesIO
12831
b1ef9690f357 [mypy] type __select__ everywhere
Laurent Peuch <cortex@worlddomination.be>
parents: 12780
diff changeset
    25
from typing import Union
4244
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
    26
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
    27
from functools import partial
12780
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
    28
from inspect import getframeinfo, stack
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    29
12831
b1ef9690f357 [mypy] type __select__ everywhere
Laurent Peuch <cortex@worlddomination.be>
parents: 12780
diff changeset
    30
from logilab.common.registry import yes, Predicate
2312
af4d8f75c5db use xml_escape
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2217
diff changeset
    31
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
    32
2644
100b81ba3a98 F [view] missing import
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2613
diff changeset
    33
from rql import nodes
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    34
1181
620ec8e6ae19 cleanup, various fix to get something working
sylvain.thenault@logilab.fr
parents: 1144
diff changeset
    35
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
    36
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
    37
from cubicweb.appobject import AppObject
708
b4728112625f move utils from cw.common to cw
sylvain.thenault@logilab.fr
parents: 707
diff changeset
    38
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
    39
from cubicweb.uilib import domid, js
2217
3a8cee8f8778 explicit display_name import
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2207
diff changeset
    40
from cubicweb.schema import display_name
633
087e3f1e87c8 more selectors update
sylvain.thenault@logilab.fr
parents: 632
diff changeset
    41
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    42
# robots control
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    43
NOINDEX = u'<meta name="ROBOTS" content="NOINDEX" />'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    44
NOFOLLOW = u'<meta name="ROBOTS" content="NOFOLLOW" />'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    45
8941
7b26fe71404f drop xhtml content-type support (closes #2065651)
Aurelien Campeas <aurelien.campeas@logilab.fr>
parents: 8666
diff changeset
    46
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
    47
TRANSITIONAL_DOCTYPE = TRANSITIONAL_DOCTYPE_NOEXT # bw compat
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    48
6769
d784d64f28d0 Backed out changeset 84b67ae41a0d: with this fix, some
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6761
diff changeset
    49
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
    50
STRICT_DOCTYPE = STRICT_DOCTYPE_NOEXT # bw compat
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    51
12780
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
    52
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
    53
def inject_html_generating_call_on_w():
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
    54
    View.debug_html_rendering = True
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
    55
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
    56
661
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
    57
# base view object ############################################################
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
    58
2656
a93ae0f6c0ad R [base classes] only AppObject remaning, no more AppRsetObject
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2644
diff changeset
    59
class View(AppObject):
8419
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    60
    """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
    61
    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
    62
    components.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    63
8419
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    64
    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
    65
    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
    66
    attributes:
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
    67
8419
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    68
    :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
    69
      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
    70
      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
    71
    :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
    72
      `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
    73
      the default)
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    74
    :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
    75
      related objects (view kinds) together
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    76
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    77
    :py:attr:`paginable`
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    78
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    79
    :py:attr:`binary`
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    80
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    81
dd222fcc85d3 [doc] cubicweb.view documentation (closes: #2099962)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8204
diff changeset
    82
    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
    83
    append method of an `UStreamIO`, except for binary views).
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    84
4702
d9e51820d0c2 fix docstring
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4459
diff changeset
    85
    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
    86
    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
    87
    function to use.
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    88
    """
816
9cd49a910fce kill Template class and 'templates' registry
sylvain.thenault@logilab.fr
parents: 781
diff changeset
    89
    __registry__ = 'views'
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
    90
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    91
    templatable = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    92
    # content_type = 'application/xhtml+xml' # text/xhtml'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    93
    binary = False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    94
    add_to_breadcrumbs = True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    95
    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
    96
    paginable = True
12780
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
    97
    debug_html_rendering = False
4244
2c3de1953d00 rename need_navigation into paginable
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4212
diff changeset
    98
1143
8d097defbf2c change the way selected/__init__ are used for AppRsetObject
sylvain.thenault@logilab.fr
parents: 1132
diff changeset
    99
    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
   100
        super(View, self).__init__(req, rset=rset, **kwargs)
12780
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   101
        self._w = None
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   102
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   103
    @property
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   104
    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
   105
        return self._cw.html_content_type()
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
   106
12780
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   107
    def w(self, text):
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   108
        if self._w is None:
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   109
            raise Exception('Error: call to %s.w before it has been set' % self)
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   110
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   111
        if self.debug_html_rendering:
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   112
            caller = getframeinfo(stack()[1][0])
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   113
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   114
            if isinstance(text, str) and re.match(r"^ *<[a-zA-Z0-9]+( .*>|>)", text):
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   115
                to_add = 'cubicweb-generated-by="%s.%s" cubicweb-from-source="%s:%s"' % (
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   116
                    self.__module__, self.__class__.__name__,
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   117
                    caller.filename, caller.lineno,
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   118
                )
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   119
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   120
                before_space, beginning_of_html = text.split("<", 1)
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   121
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   122
                # when it's a tag without attribues like "<b>"
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   123
                if re.match(r"^ *<[a-zA-Z0-9]+>", text):
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   124
                    tag_name, rest = beginning_of_html.split(">", 1)
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   125
                    rest = ">" + rest
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   126
                else:
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   127
                    tag_name, rest = beginning_of_html.split(" ", 1)
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   128
                    rest = " " + rest
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   129
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   130
                text = "%(before_space)s<%(tag_name)s %(to_add)s%(rest)s" % {
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   131
                    "before_space": before_space,
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   132
                    "tag_name": tag_name,
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   133
                    "to_add": to_add,
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   134
                    "rest": rest,
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   135
                }
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   136
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   137
        return self._w(text)
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   138
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   139
    def set_stream(self, w=None):
12780
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   140
        if self._w is not None:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   141
            return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   142
        if w is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   143
            if self.binary:
10211
59a77e8847bc [view] Use io.BytesIO as stream for binary views
Rémi Cardona <remi.cardona@free.fr>
parents: 10068
diff changeset
   144
                self._stream = stream = BytesIO()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   145
            else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   146
                self._stream = stream = UStringIO()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   147
            w = stream.write
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   148
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   149
            stream = None
12780
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   150
        self._w = w
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   151
        return stream
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   152
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   153
    # main view interface #####################################################
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
   154
1723
30c3a713ab61 View.dispatch -> View.render
sylvain.thenault@logilab.fr
parents: 1511
diff changeset
   155
    def render(self, w=None, **context):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   156
        """called to render a view object for a result set.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   157
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   158
        This method is a dispatched to an actual method selected
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   159
        according to optional row and col parameters, which are locating
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   160
        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
   161
1132
96752791c2b6 pylint cleanup
sylvain.thenault@logilab.fr
parents: 986
diff changeset
   162
        * if row is specified, `cell_call` is called
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   163
        * 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
   164
          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
   165
          called
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   166
        """
6922
cb1dd14a768f [view] fix/enhance view.render
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6909
diff changeset
   167
        # XXX use .cw_row/.cw_col
1132
96752791c2b6 pylint cleanup
sylvain.thenault@logilab.fr
parents: 986
diff changeset
   168
        row = context.get('row')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   169
        if row is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   170
            context.setdefault('col', 0)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   171
            view_func = self.cell_call
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   172
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   173
            view_func = self.call
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   174
        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
   175
        try:
33343d6eae0a [view] log error on view_func call
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6458
diff changeset
   176
            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
   177
        except Exception:
6563
33343d6eae0a [view] log error on view_func call
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6458
diff changeset
   178
            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
   179
            raise
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   180
        # return stream content if we have created it
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   181
        if stream is not None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   182
            return self._stream.getvalue()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   183
2795
59965167bef3 move tal_render to View
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2788
diff changeset
   184
    def tal_render(self, template, variables):
59965167bef3 move tal_render to View
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2788
diff changeset
   185
        """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
   186
        dictionary as context
59965167bef3 move tal_render to View
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2788
diff changeset
   187
        """
59965167bef3 move tal_render to View
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2788
diff changeset
   188
        from cubicweb.ext.tal import CubicWebContext
59965167bef3 move tal_render to View
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2788
diff changeset
   189
        context = CubicWebContext()
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   190
        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
   191
                        '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
   192
        context.update(variables)
59965167bef3 move tal_render to View
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2788
diff changeset
   193
        output = UStringIO()
59965167bef3 move tal_render to View
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2788
diff changeset
   194
        template.expand(context, output)
59965167bef3 move tal_render to View
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2788
diff changeset
   195
        return output.getvalue()
59965167bef3 move tal_render to View
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2788
diff changeset
   196
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   197
    # should default .call() method add a <div classs="section"> around each
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   198
    # rset item
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   199
    add_div_section = True
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
   200
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   201
    def call(self, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   202
        """the view is called for an entire result set, by default loop
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   203
        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
   204
        particular row
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   205
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   206
        Views applicable on None result sets have to override this method
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   207
        """
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   208
        rset = self.cw_rset
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   209
        if rset is None:
8204
332596be995e [view] fix error messages of NotImplementedError
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8174
diff changeset
   210
            raise NotImplementedError("%r an rset is required" % self)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   211
        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
   212
        # 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
   213
        # specific view
cb1dd14a768f [view] fix/enhance view.render
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6909
diff changeset
   214
        if rset.rowcount != 1:
cb1dd14a768f [view] fix/enhance view.render
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6909
diff changeset
   215
            kwargs.setdefault('initargs', self.cw_extra_kwargs)
10609
e2d8e81bfe68 [py3k] import range using six.moves
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10211
diff changeset
   216
            for i in range(len(rset)):
6922
cb1dd14a768f [view] fix/enhance view.render
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6909
diff changeset
   217
                if wrap:
cb1dd14a768f [view] fix/enhance view.render
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6909
diff changeset
   218
                    self.w(u'<div class="section">')
cb1dd14a768f [view] fix/enhance view.render
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6909
diff changeset
   219
                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
   220
                if wrap:
cb1dd14a768f [view] fix/enhance view.render
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6909
diff changeset
   221
                    self.w(u"</div>")
cb1dd14a768f [view] fix/enhance view.render
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6909
diff changeset
   222
        else:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   223
            if wrap:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   224
                self.w(u'<div class="section">')
6922
cb1dd14a768f [view] fix/enhance view.render
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6909
diff changeset
   225
            kwargs.setdefault('col', 0)
cb1dd14a768f [view] fix/enhance view.render
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6909
diff changeset
   226
            self.cell_call(row=0, **kwargs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   227
            if wrap:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   228
                self.w(u"</div>")
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   229
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   230
    def cell_call(self, row, col, **kwargs):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   231
        """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
   232
        raise NotImplementedError(repr(self))
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
   233
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   234
    def linkable(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   235
        """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
   236
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   237
        by default views without title are not meant to be displayed
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   238
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   239
        if not getattr(self, 'title', None):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   240
            return False
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   241
        return True
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   242
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   243
    def is_primary(self):
4045
f4a52abb6f4f cw 3.6 api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 3998
diff changeset
   244
        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
   245
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   246
    def url(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   247
        """return the url associated with this view. Should not be
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   248
        necessary for non linkable views, but a default implementation
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   249
        is provided anyway.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   250
        """
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   251
        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
   252
        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
   253
            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
   254
        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
   255
        if len(coltypes) == 1:
10669
155c29e0ed1c [py3k] use next builtin instead of next method
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10666
diff changeset
   256
            etype = next(iter(coltypes))
4045
f4a52abb6f4f cw 3.6 api update
Sandrine Ribeau <sandrine.ribeau@logilab.fr>
parents: 3998
diff changeset
   257
            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
   258
                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
   259
                    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
   260
                    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
   261
            # 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
   262
            # 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
   263
            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
   264
            # 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
   265
            # "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
   266
            # True
93853b6f3bad move all view.url() logic in a single implementation
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2418
diff changeset
   267
            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
   268
                             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
   269
            if norestriction:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   270
                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
   271
        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
   272
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   273
    def set_request_content_type(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   274
        """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
   275
        self._cw.set_content_type(self.content_type)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   276
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   277
    # view utilities ##########################################################
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   278
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
   279
    def wview(self, __vid, rset=None, __fallback_vid=None, **kwargs):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   280
        """shortcut to self.view method automatically passing self.w as argument
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   281
        """
12780
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   282
        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
   283
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   284
    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
   285
        self._cw.html_headers.write(data)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   286
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   287
    def wdata(self, data):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   288
        """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
   289
        self.w(xml_escape(data))
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   290
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   291
    def html_headers(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   292
        """return a list of html headers (eg something to be inserted between
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   293
        <head> and </head> of the returned page
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   294
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   295
        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
   296
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   297
        return [NOINDEX]
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
   298
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   299
    def page_title(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   300
        """returns a title according to the result set - used for the
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   301
        title in the HTML header
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   302
        """
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   303
        vtitle = self._cw.form.get('vtitle')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   304
        if vtitle:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   305
            return self._cw._(vtitle)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   306
        # 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
   307
        # seem clear enough
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   308
        vtitle = getattr(self, 'title', None) or u''
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   309
        if vtitle:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   310
            vtitle = self._cw._(vtitle)
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   311
        rset = self.cw_rset
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   312
        if rset and rset.rowcount:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   313
            if rset.rowcount == 1:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   314
                try:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   315
                    entity = rset.complete_entity(0, 0)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   316
                    # use long_title to get context information if any
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   317
                    clabel = entity.dc_long_title()
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   318
                except NotAnEntity:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   319
                    clabel = display_name(self._cw, rset.description[0][0])
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   320
                    clabel = u'%s (%s)' % (clabel, vtitle)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   321
            else :
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   322
                etypes = rset.column_types(0)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   323
                if len(etypes) == 1:
10669
155c29e0ed1c [py3k] use next builtin instead of next method
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10666
diff changeset
   324
                    etype = next(iter(etypes))
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   325
                    clabel = display_name(self._cw, etype, 'plural')
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   326
                else :
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   327
                    clabel = u'#[*] (%s)' % vtitle
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   328
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   329
            clabel = vtitle
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   330
        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
   331
6038
5c5d819e8e93 small cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5725
diff changeset
   332
    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
   333
              table=False):
3809
1b9b51ee543e [web ui] PrimaryView.render_attributes now uses a table
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 3782
diff changeset
   334
        """read-only field"""
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   335
        if w is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   336
            w = self.w
3809
1b9b51ee543e [web ui] PrimaryView.render_attributes now uses a table
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 3782
diff changeset
   337
        if table:
1b9b51ee543e [web ui] PrimaryView.render_attributes now uses a table
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 3782
diff changeset
   338
            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
   339
        else:
1b9b51ee543e [web ui] PrimaryView.render_attributes now uses a table
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 3782
diff changeset
   340
            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
   341
        if show_label and label:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   342
            if tr:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   343
                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
   344
            if table:
1b9b51ee543e [web ui] PrimaryView.render_attributes now uses a table
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 3782
diff changeset
   345
                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
   346
            else:
6909
b8171392de16 [view] missing class on label span
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6864
diff changeset
   347
                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
   348
        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
   349
            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
   350
                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
   351
            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
   352
                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
   353
        else:
1b9b51ee543e [web ui] PrimaryView.render_attributes now uses a table
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 3782
diff changeset
   354
            w(u'<span>%s</span></div>' % value)
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   355
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   356
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
   357
640
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 635
diff changeset
   358
# concrete views base classes #################################################
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 635
diff changeset
   359
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 635
diff changeset
   360
class EntityView(View):
843
5676811ef760 cleanup
sylvain.thenault@logilab.fr
parents: 822
diff changeset
   361
    """base class for views applying on an entity (i.e. uniform result set)"""
12831
b1ef9690f357 [mypy] type __select__ everywhere
Laurent Peuch <cortex@worlddomination.be>
parents: 12780
diff changeset
   362
    __select__: Union[None, str, Predicate] = 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
   363
    category = _('entityview')
640
8e64f12be69c drop EntityAction usage in cw, upgrade rql_condition and friends
sylvain.thenault@logilab.fr
parents: 635
diff changeset
   364
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
   365
    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
   366
        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
   367
            # * 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
   368
            #   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
   369
            # * 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
   370
            #   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
   371
            #
f19e3203dff6 [view] fix TypeError when calling req.view('vid', entity=entity) (closes #1947474)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
   372
            # 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
   373
            #
f19e3203dff6 [view] fix TypeError when calling req.view('vid', entity=entity) (closes #1947474)
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7815
diff changeset
   374
            # 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
   375
            # .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
   376
            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
   377
            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
   378
                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
   379
            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
   380
        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
   381
            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
   382
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
   383
    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
   384
        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
   385
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
   386
    def entity_call(self, entity, **kwargs):
8204
332596be995e [view] fix error messages of NotImplementedError
Nicolas Chauvat <nicolas.chauvat@logilab.fr>
parents: 8174
diff changeset
   387
        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
   388
6926
2cda8f1b4fae cleanups
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6922
diff changeset
   389
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   390
class StartupView(View):
843
5676811ef760 cleanup
sylvain.thenault@logilab.fr
parents: 822
diff changeset
   391
    """base class for views which doesn't need a particular result set to be
9492
c7fc56eecd1a English typography
Dimitri Papadopoulos <dimitri.papadopoulos@cea.fr>
parents: 9256
diff changeset
   392
    displayed (so they can always be displayed!)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   393
    """
12831
b1ef9690f357 [mypy] type __select__ everywhere
Laurent Peuch <cortex@worlddomination.be>
parents: 12780
diff changeset
   394
    __select__: Union[None, str, Predicate] = none_rset()
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   395
7670
6397a9051f65 [boxes] closes #1832844: translate views category in possible views boxes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7346
diff changeset
   396
    category = _('startupview')
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   397
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   398
    def html_headers(self):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   399
        """return a list of html headers (eg something to be inserted between
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   400
        <head> and </head> of the returned page
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   401
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   402
        by default startup views are indexed
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   403
        """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   404
        return []
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   405
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   406
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   407
class EntityStartupView(EntityView):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   408
    """base class for entity views which may also be applied to None
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   409
    result set (usually a default rql is provided by the view class)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   410
    """
12831
b1ef9690f357 [mypy] type __select__ everywhere
Laurent Peuch <cortex@worlddomination.be>
parents: 12780
diff changeset
   411
    __select__: Union[None, str, Predicate] = none_rset() | non_final_entity()
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
   412
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   413
    default_rql = None
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
   414
2418
8f06e4f02733 optional rset
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2312
diff changeset
   415
    def __init__(self, req, rset=None, **kwargs):
2890
fdcb8a2bb6eb fix __init__ parameters
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 2822
diff changeset
   416
        super(EntityStartupView, self).__init__(req, rset=rset, **kwargs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   417
        if rset is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   418
            # this instance is not in the "entityview" category
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   419
            self.category = 'startupview'
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   420
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   421
    def startup_rql(self):
873
3d9df99b0bfa cleanup
sylvain.thenault@logilab.fr
parents: 843
diff changeset
   422
        """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
   423
        return self.default_rql
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
   424
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
   425
    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
   426
        """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
   427
        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
   428
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   429
    def call(self, **kwargs):
873
3d9df99b0bfa cleanup
sylvain.thenault@logilab.fr
parents: 843
diff changeset
   430
        """override call to execute rql returned by the .startup_rql method if
3d9df99b0bfa cleanup
sylvain.thenault@logilab.fr
parents: 843
diff changeset
   431
        necessary
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   432
        """
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   433
        rset = self.cw_rset
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   434
        if rset is None:
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   435
            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
   436
        if rset:
10609
e2d8e81bfe68 [py3k] import range using six.moves
Rémi Cardona <remi.cardona@logilab.fr>
parents: 10211
diff changeset
   437
            for i in range(len(rset)):
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
   438
                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
   439
        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
   440
            self.no_entities(**kwargs)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   441
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
   442
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   443
class AnyRsetView(View):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   444
    """base class for views applying on any non empty result sets"""
12831
b1ef9690f357 [mypy] type __select__ everywhere
Laurent Peuch <cortex@worlddomination.be>
parents: 12780
diff changeset
   445
    __select__: Union[None, str, Predicate] = nonempty_rset()
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
   446
7670
6397a9051f65 [boxes] closes #1832844: translate views category in possible views boxes
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7346
diff changeset
   447
    category = _('anyrsetview')
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
   448
2203
efdd3a9f9028 update to new rql get_description api
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 1999
diff changeset
   449
    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
   450
        """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
   451
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   452
        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
   453
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   454
        :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
   455
                          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
   456
        :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
   457
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   458
        :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
   459
        :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
   460
        """
370
7e76f651314b fix rset xml view
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 369
diff changeset
   461
        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
   462
            translate = partial(display_name, self._cw)
370
7e76f651314b fix rset xml view
Sylvain Thenault <sylvain.thenault@logilab.fr>
parents: 369
diff changeset
   463
        else:
8011
23552e79316f [column labels] full display_name prototype compat
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 7959
diff changeset
   464
            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
   465
        # 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
   466
        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
   467
        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
   468
        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
   469
        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
   470
            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
   471
        return labels
543
c0f2b6378f70 simplification of lazy tabs mechanism
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 522
diff changeset
   472
7938
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   473
    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
   474
        """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
   475
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   476
        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
   477
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   478
        :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
   479
        :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
   480
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   481
        :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
   482
                        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
   483
                        etypes name.
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   484
        :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
   485
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   486
        :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
   487
        :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
   488
        """
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   489
        label = default
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   490
        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
   491
            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
   492
            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
   493
                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
   494
            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
   495
        return label
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   496
80c6e2155c3d AnyRsetView: Refactor the columns_name method and update doc.
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 7833
diff changeset
   497
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   498
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   499
# concrete template base classes ##############################################
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   500
816
9cd49a910fce kill Template class and 'templates' registry
sylvain.thenault@logilab.fr
parents: 781
diff changeset
   501
class MainTemplate(View):
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   502
    """main template are primary access point to render a full HTML page.
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   503
    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
   504
    one to display error if the first one failed
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   505
    """
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   506
8976
aeb7d400ee92 [view] return HTML5 doctype. Closes #2869426
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 8941
diff changeset
   507
    doctype = '<!DOCTYPE html>'
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   508
1424
0a440312913b set_stream simplification
sylvain.thenault@logilab.fr
parents: 1421
diff changeset
   509
    def set_stream(self, w=None):
12780
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   510
        if self._w is not None:
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   511
            return
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   512
        if w is None:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   513
            if self.binary:
10211
59a77e8847bc [view] Use io.BytesIO as stream for binary views
Rémi Cardona <remi.cardona@free.fr>
parents: 10068
diff changeset
   514
                self._stream = stream = BytesIO()
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   515
            else:
3451
6b46d73823f5 [api] work in progress, use __regid__, cw_*, etc.
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents: 3369
diff changeset
   516
                self._stream = stream = HTMLStream(self._cw)
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   517
            w = stream.write
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   518
        else:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   519
            stream = None
12780
8caa109dfe94 [debug] add in each html snippet from where it has been generated in the code
Laurent Peuch <cortex@worlddomination.be>
parents: 12567
diff changeset
   520
        self._w = w
0
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   521
        return stream
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   522
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   523
    def write_doctype(self, xmldecl=True):
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   524
        assert isinstance(self._stream, HTMLStream)
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   525
        self._stream.doctype = self.doctype
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   526
        if not xmldecl:
b97547f5f1fa Showtime !
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   527
            self._stream.xmldecl = u''
661
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   528
822
e3d8db01f3f5 test_views fixes
sylvain.thenault@logilab.fr
parents: 819
diff changeset
   529
    def linkable(self):
e3d8db01f3f5 test_views fixes
sylvain.thenault@logilab.fr
parents: 819
diff changeset
   530
        return False
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   531
661
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   532
# concrete component base classes #############################################
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
class ReloadableMixIn(object):
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   535
    """simple mixin for reloadable parts of UI"""
1433
091ac3ba5d51 remove trailing white spaces
sylvain.thenault@logilab.fr
parents: 1432
diff changeset
   536
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   537
    @property
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   538
    def domid(self):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   539
        return domid(self.__regid__)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   540
661
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   541
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   542
class Component(ReloadableMixIn, View):
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   543
    """base class for components"""
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   544
    __registry__ = 'components'
12831
b1ef9690f357 [mypy] type __select__ everywhere
Laurent Peuch <cortex@worlddomination.be>
parents: 12780
diff changeset
   545
    __select__: Union[None, str, Predicate] = yes()
661
4f61eb8a96b7 properly kill/depreciate component base class, only keep Component
sylvain.thenault@logilab.fr
parents: 660
diff changeset
   546
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   547
    # 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
   548
    htmlclass = 'mainRelated'
6140
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   549
    @property
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   550
    def cssclass(self):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   551
        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
   552
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   553
    # XXX should rely on ReloadableMixIn.domid
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   554
    @property
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   555
    def domid(self):
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   556
        return '%sComponent' % domid(self.__regid__)
65a619eb31c4 [boxes] introduce new boxes system
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 6047
diff changeset
   557
5556
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5533
diff changeset
   558
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5533
diff changeset
   559
class Adapter(AppObject):
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5533
diff changeset
   560
    """base class for adapters"""
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5533
diff changeset
   561
    __registry__ = 'adapters'
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5533
diff changeset
   562
9ab2b4c74baf [entity] introduce a new 'adapters' registry
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5533
diff changeset
   563
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
   564
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
   565
    """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
   566
    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
   567
        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
   568
            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
   569
        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
   570
            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
   571
                                                    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
   572
        Adapter.__init__(self, _cw, **kwargs)