summaryrefslogtreecommitdiff
path: root/repoze/bfg/zcml.py
blob: bc136055aec38bd1a4d46cd9c2e43409a5d9cbd3 (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
import os

from zope.schema import TextLine
from zope.configuration.fields import Path
from zope.interface import Interface
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.security.zcml import Permission

from repoze.bfg.interfaces import IRequest
from repoze.bfg.interfaces import IViewFactory

from repoze.bfg.template import ViewPageTemplateFile
from repoze.bfg.template import PageTemplateFile

class ViewBase:
    def __init__(self, context, request):
        self.context = context
        self.request = request

    def __call__(self, *arg, **kw):
        return self.index(*arg, **kw)

def page(_context,
         permission,
         for_,
         name="",
         template=None,
         class_=None,
         ):

    # XXX we do nothing yet with permission

    if not (class_ or template):
        raise ConfigurationError("Must specify a class or a template")

    if template:
        template = os.path.abspath(str(_context.path(template)))
        if not os.path.isfile(template):
            raise ConfigurationError("No such file", template)

        template_inst = PageTemplateFile(template)

    def view_factory(context, request):
        if template:
            if class_ is None:
                base = ViewBase
            else:
                base = class_
            class ViewClass(base):
                __name__ = name
                index = ViewPageTemplateFile(template_inst)
            return ViewClass(context, request)
                    
        else:
            return class_(context, request)
        
    if for_ is not None:
        _context.action(
            discriminator = None,
            callable = provideInterface,
            args = ('', for_)
            )

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

class IPageDirective(Interface):
    """
    The page directive is used to create views that provide a single
    url or page.

    The page directive creates a new view class from a given template
    and/or class and registers it.
    """

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

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

    class_ = GlobalObject(
        title=u"Class",
        description=u"A class that provides a __call__ used by the view.",
        required=False,
        )

    name = TextLine(
        title=u"The name of the page (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 page.",
        description=u"""
        Refers to a file containing a page template (should end in
        extension '.pt' or '.html').""",
        required=False
        )