Exemple #1
0
class TagLoaderTests(FlattenTestCase):
    """
    Tests for L{TagLoader}.
    """
    def setUp(self):
        self.loader = TagLoader(tags.i('test'))


    def test_interface(self):
        """
        An instance of L{TagLoader} provides L{ITemplateLoader}.
        """
        self.assertTrue(verifyObject(ITemplateLoader, self.loader))


    def test_loadsList(self):
        """
        L{TagLoader.load} returns a list, per L{ITemplateLoader}.
        """
        self.assertIsInstance(self.loader.load(), list)


    def test_flatten(self):
        """
        L{TagLoader} can be used in an L{Element}, and flattens as the tag used
        to construct the L{TagLoader} would flatten.
        """
        e = Element(self.loader)
        self.assertFlattensImmediately(e, b'<i>test</i>')
class TagLoaderTests(FlattenTestCase):
    """
    Tests for L{TagLoader}.
    """
    def setUp(self):
        self.loader = TagLoader(tags.i('test'))


    def test_interface(self):
        """
        An instance of L{TagLoader} provides L{ITemplateLoader}.
        """
        self.assertTrue(verifyObject(ITemplateLoader, self.loader))


    def test_loadsList(self):
        """
        L{TagLoader.load} returns a list, per L{ITemplateLoader}.
        """
        self.assertIsInstance(self.loader.load(), list)


    def test_flatten(self):
        """
        L{TagLoader} can be used in an L{Element}, and flattens as the tag used
        to construct the L{TagLoader} would flatten.
        """
        e = Element(self.loader)
        self.assertFlattensImmediately(e, '<i>test</i>')
Exemple #3
0
class Plating(object):
    """
    A L{Plating} is a container which can be used to generate HTML from data.

    Its name is derived both from tem-I{plating} and I{chrome plating}.
    """

    CONTENT = "klein:plating:content"

    def __init__(self,
                 defaults=None,
                 tags=None,
                 presentation_slots=frozenset()):
        """
        """
        self._defaults = {} if defaults is None else defaults
        self._loader = TagLoader(tags)
        self._presentationSlots = {self.CONTENT} | set(presentation_slots)

    def routed(self, routing, tags):
        """
        """
        def mydecorator(method):
            loader = TagLoader(tags)

            @modified("plating route renderer", method, routing)
            @bindable
            @inlineCallbacks
            def mymethod(instance, request, *args, **kw):
                data = yield _call(instance, method, request, *args, **kw)
                if _should_return_json(request):
                    json_data = self._defaults.copy()
                    json_data.update(data)
                    for ignored in self._presentationSlots:
                        json_data.pop(ignored, None)
                    text_type = u'json'
                    result = json_serialize(json_data)
                else:
                    data[self.CONTENT] = loader.load()
                    text_type = u'html'
                    result = self._elementify(instance, data)
                request.setHeader(b'content-type',
                                  (u'text/{format}; charset=utf-8'.format(
                                      format=text_type).encode("charmap")))
                returnValue(result)

            return method

        return mydecorator

    def _elementify(self, instance, to_fill_with):
        """
        Convert this L{Plating} into a L{PlatedElement}.
        """
        slot_data = self._defaults.copy()
        slot_data.update(to_fill_with)
        [loaded] = self._loader.load()
        loaded = loaded.clone()
        return PlatedElement(slot_data=slot_data,
                             preloaded=loaded,
                             boundInstance=instance,
                             presentationSlots=self._presentationSlots)

    def widgeted(self, function):
        @modified("Plating.widget renderer", function)
        @bindable
        def wrapper(instance, *a, **k):
            data = _call(instance, function, *a, **k)
            return self._elementify(instance, data)

        function.widget = wrapper
        return function
Exemple #4
0
class Plating(object):
    """
    A L{Plating} is a container which can be used to generate HTML from data.

    Its name is derived both from tem-I{plating} and I{chrome plating}.
    """

    CONTENT = "klein:plating:content"

    def __init__(self, defaults=None, tags=None, presentation_slots=()):
        """"""
        self._defaults = {} if defaults is None else defaults
        self._loader = TagLoader(tags)
        self._presentationSlots = {self.CONTENT} | set(presentation_slots)
        self._renderers = {}

    def renderMethod(self, renderer):
        """
        Add a render method to this L{Plating} object that can be used in the
        top-level template.

        The name of the renderer to use within the template is the name of the
        decorated function.
        """
        self._renderers[text_type(originalName(renderer))] = renderer
        return renderer

    def routed(self, routing, tags):
        """"""
        def mydecorator(method):
            loader = TagLoader(tags)

            @modified("plating route renderer", method, routing)
            @bindable
            @inlineCallbacks
            def mymethod(instance: Any, request: IRequest, *args: Any,
                         **kw: Any) -> Any:
                data = yield _call(instance, method, request, *args, **kw)
                if _should_return_json(request):
                    json_data = self._defaults.copy()
                    json_data.update(data)
                    for ignored in self._presentationSlots:
                        json_data.pop(ignored, None)
                    text_type = "json"
                    ready = yield resolveDeferredObjects(json_data)
                    result = dumps(ready)
                else:
                    data[self.CONTENT] = loader.load()
                    text_type = "html"
                    result = self._elementify(instance, data)
                request.setHeader(
                    b"content-type",
                    ("text/{format}; charset=utf-8".format(
                        format=text_type).encode("charmap")),
                )
                returnValue(result)

            return method

        return mydecorator

    def _elementify(self, instance, to_fill_with):
        """
        Convert this L{Plating} into a L{PlatedElement}.
        """
        slot_data = self._defaults.copy()
        slot_data.update(to_fill_with)
        [loaded] = self._loader.load()
        loaded = loaded.clone()
        return PlatedElement(
            slot_data=slot_data,
            preloaded=loaded,
            renderers=self._renderers,
            boundInstance=instance,
            presentationSlots=self._presentationSlots,
        )

    @attr.s
    class _Widget(object):
        """
        Implementation of L{Plating.widgeted}.  This is a L{callable}
        descriptor that records the instance to which its wrapped
        function is bound, if any.  Its L{widget} method then passes
        that instance or L{None} and the result of invoking the
        function (or now bound method) to the creating L{Plating}
        instance's L{Plating._elementify} to construct a
        L{PlatedElement}.
        """

        _plating = attr.ib(type="Plating")
        _function = attr.ib(type=Callable[..., Any])
        _instance = attr.ib(type=object)

        def __call__(self, *args, **kwargs):
            return self._function(*args, **kwargs)

        def __get__(self, instance, owner=None):
            return self.__class__(
                self._plating,
                self._function.__get__(instance, owner),
                instance=instance,
            )

        def widget(self, *args, **kwargs):
            """
            Construct a L{PlatedElement} the rendering of this widget.
            """
            data = self._function(*args, **kwargs)
            return self._plating._elementify(self._instance, data)

        def __getattr__(self, attr):
            return getattr(self._function, attr)

    def widgeted(self, function):
        """
        A decorator that turns a function into a renderer for an
        element without a L{Klein.route}.  Use this to create reusable
        template elements.
        """
        return self._Widget(self, function, None)
Exemple #5
0
class Plating(object):
    """
    A L{Plating} is a container which can be used to generate HTML from data.

    Its name is derived both from tem-I{plating} and I{chrome plating}.
    """

    CONTENT = "klein:plating:content"

    def __init__(self, defaults=None, tags=None,
                 presentation_slots=frozenset()):
        """
        
        """
        self._defaults = {} if defaults is None else defaults
        self._loader = TagLoader(tags)
        self._presentation_slots = {self.CONTENT} | set(presentation_slots)

    def routed(self, routing, content_template):
        """
        
        """
        @wraps(routing)
        def mydecorator(method):
            loader = TagLoader(content_template)
            @routing
            @wraps(method)
            def mymethod(request, *args, **kw):
                data = method(request, *args, **kw)
                if _should_return_json(request):
                    json_data = self._defaults.copy()
                    json_data.update(data)
                    for ignored in self._presentation_slots:
                        json_data.pop(ignored, None)
                    request.setHeader(b'content-type',
                                      b'text/json; charset=utf-8')
                    return json_serialize(json_data)
                else:
                    request.setHeader(b'content-type',
                                      b'text/html; charset=utf-8')
                    data[self.CONTENT] = loader.load()
                    return self._elementify(data)
            return method
        return mydecorator

    def _elementify(self, to_fill_with):
        """
        
        """
        slot_data = self._defaults.copy()
        slot_data.update(to_fill_with)
        [loaded] = self._loader.load()
        loaded = loaded.clone()
        return PlatedElement(slot_data=slot_data,
                             preloaded=loaded)

    def widgeted(self, function):
        """
        
        """
        @wraps(function)
        def wrapper(*a, **k):
            data = function(*a, **k)
            return self._elementify(data)
        wrapper.__name__ += ".widget"
        function.widget = wrapper
        return function