summaryrefslogtreecommitdiff
path: root/repoze/bfg/zcml.py
blob: 7d81527d2ed3c73b0dc069ff0de5fe7e7c8d0b79 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import os

from zope.component.zcml import handler
from zope.component.interface import provideInterface
from zope.configuration.exceptions import ConfigurationError
from zope.configuration.fields import GlobalObject
from zope.configuration.fields import Path

from zope.interface import Interface
from zope.interface import implements
from zope.interface import classProvides

from zope.schema import TextLine

from repoze.bfg.interfaces import IRequest
from repoze.bfg.interfaces import ITemplateFactory
from repoze.bfg.interfaces import ITemplate
from repoze.bfg.interfaces import IViewPermission
from repoze.bfg.interfaces import IView

from repoze.bfg.template import Z3CPTTemplateFactory
from repoze.bfg.template import render_template_to_response

from repoze.bfg.security import ViewPermissionFactory

class TemplateOnlyViewFactory(object):
    """ Pickleable template-only view factory """
    classProvides(ITemplateFactory)
    implements(IView)

    def __init__(self, template):
        self.template = template

    def __call__(self, context, request):
        kw = dict(view=self, context=context, request=request)
        return render_template_to_response(self.template, **kw)
        
def view(_context,
         permission=None,
         for_=None,
         view=None,
         name="",
         template=None,
         ):

    if (template and view):
        raise ConfigurationError(
            'One of template or view must be specified, not both')

    if template:
        template_abs = os.path.abspath(str(_context.path(template)))
        if not os.path.exists(template_abs):
            raise ConfigurationError('No template file named %s' % template_abs)
        utility = Z3CPTTemplateFactory(template_abs)
        _context.action(
            discriminator = ('utility', ITemplate, template_abs),
            callable = handler,
            args = ('registerUtility', utility, ITemplate, template_abs),
            )
        view = TemplateOnlyViewFactory(template_abs)

    if not view:
        raise ConfigurationError(
            'Neither template nor factory was specified, though one must be '
            'specified.')

    if for_ is not None:
        _context.action(
            discriminator = None,
            callable = provideInterface,
            args = ('', for_)
            )

    if permission:
        pfactory = ViewPermissionFactory(permission)
        _context.action(
            discriminator = ('permission', for_,name, IRequest,IViewPermission),
            callable = handler,
            args = ('registerAdapter',
                    pfactory, (for_, IRequest), IViewPermission, name,
                    _context.info),
            )

    _context.action(
        discriminator = ('view', for_, name, IRequest, IView),
        callable = handler,
        args = ('registerAdapter',
                view, (for_, IRequest), IView, name,
                _context.info),
        )

class IViewDirective(Interface):
    for_ = GlobalObject(
        title=u"The interface or class this view is for.",
        required=False
        )

    permission = TextLine(
        title=u"Permission",
        description=u"The permission needed to use the view.",
        required=False
        )

    view = GlobalObject(
        title=u"",
        description=u"The view function",
        required=False,
        )

    name = TextLine(
        title=u"The name of the view",
        description=u"""
        The name shows up in URLs/paths. For example 'foo' or
        'foo.html'.""",
        required=False,
        )

    template = Path(
        title=u"The name of a template that implements the view.",
        description=u"""Refers to a file containing a z3c.pt page template""",
        required=False
        )