Comments (2)
import sys
from functools import wraps
from klein import route, run
from twisted.web.template import (
tags, slot, TagLoader, Element, XMLString, XMLFile
)
from twisted.python.modules import getModule
def _callingModuleName(extra=0):
"""
Return the name of the calling module.
"""
return sys._getframe(2 + extra).f_globals('__name__')
_kw2loaderMapping = {
'tags': TagLoader,
'string': XMLString,
'filename': lambda fn:
XMLFile(getModule(_callingModuleName(1))
.filePath.sibling(fn))
}
def _kw2loader(kwargs):
"""
Convert the given C{kwargs} into a loader::
_kw2loader(dict(tags=[...]))
returns a L{TagLoader} with the given twisted.web.template stan objects, ::
_kw2loader(dict(string='<html ...></html>'))
will create a L{XMLString} from some XML, and ::
_kw2loader(dict(file='foo.xml'))
will create a L{XMLFile} from an XML file next to the Python file it's
defined in.
@return: a template loader based on the keyword arguments.
@rtype: L{ITemplateLoader}
"""
if len(kwargs) != 1:
raise TypeError("pass only one type of loader, not {}"
.format(repr(kwargs.keys())))
[[key, value]] = kwargs.items()
return _kw2loaderMapping[key](value)
class Plating(object):
"""
L{Plating} (as in: chrome-plating) represents the common elements of a page
(borders, navigation, footer, etc) which can be applied to the content of
multiple pages.
"""
def __init__(self, *args, **kw):
"""
Create L{Plating} with a set of default values and a loader.
@param args: L{Plating} takes a single optional positional argument,
the default values for all the slots in its template.
@param kw: A loader for the plating portions of the template
(header/footer/navigation) based on the rules explained in
L{_kw2loader}. This template should have at least one slot, called
C{"content"}.
"""
if args:
[self.defaults] = args
else:
self.defaults = {}
self.loader = _kw2loader(kw)
def content(self, **kw):
"""
L{Plating.content} is a decorator used to decorate a function which
produces a dictionary of slot data.
@param kw: A loader for the content portions of the template, which
will be filled out with slot values from the return value of the
decorated function.
"""
loader = _kw2loader(kw)
def decorate(thunk):
@wraps(thunk)
def decorator(*a, **k):
slotData = self.defaults.copy()
toFillWith = thunk(*a, **k)
slotData.update(toFillWith)
slotData.update(content=Element(loader=loader))
[loaded] = self.loader.load()
loaded = loaded.clone()
return Element(
loader=TagLoader(
loaded.fillSlots(
**slotData
)
)
)
return decorator
return decorate
plating = Plating(
dict(
title=u"JUST A TITLE",
content=u"NEVER MIND THE CONTENT",
),
tags=tags.html(
tags.head(tags.title(slot("title"))),
tags.body(
tags.h1(slot("title")),
tags.div(slot("content"),
Class="content")
)
),
)
@route('/')
@plating.content(tags=tags.h2(tags.em(slot("subtitle"))))
def something(request):
"""
Example usage of L{Plating}.
"""
return dict(
title=u"title displayed here",
subtitle=u"and this stands in for some content"
)
widgetPlating = Plating(
tags=tags.div(
tags.div(slot("title"), style="border: thin solid red;"),
tags.div(slot("content"), style="border: thin solid green;"),
style="border: thin solid blue;"
)
)
@widgetPlating.content(tags=tags.div(slot("widget-contents")))
def widget(n):
"""
A widget that fills a slot.
"""
return {
"title": u"widget-{}".format(n),
"widget-contents": "the main event for widget {}".format(n)
}
@route('/title')
@plating.content(tags=[])
def titleOnly(request):
"""
Show the title only; fill out the content slot with nothing.
"""
return dict(
subtitle=u"title only"
)
@route("/widget")
@plating.content(tags=[
tags.div(slot("blub"), style="width: 49%; float: left"),
tags.div(slot("blab"), style="width: 49%; float: left")
])
def widgetPage(request):
"""
A page with 2 widgets, each with its own common plating.
"""
return {
"blub": widget(1),
"blab": widget(2),
}
run('localhost', 9000)
from klein.
Worth noting: nothing about this even attempts to do MIME negotiation, so that's still left as an exercise for the reader.
from klein.
Related Issues (20)
- request.args and request.content from curl HOT 1
- pydal select().as_list() return error HOT 1
- Use python-info-action
- Enable Read-The-docs pull builds HOT 4
- Fix tox -e coverage-py39-twtrunk HOT 4
- Klein uses deprecated twisted.python.compat.intToBytes
- Proposing a PR to fix a few small typos HOT 2
- documentation on composition HOT 1
- Documentation on readthedocs.io is not being updated HOT 2
- Why do client socket resets cause pending Deferred to be cancelled? HOT 4
- klein.test.test_form.TestForms.test_cookieWithToken fails with treq 22.1.0 HOT 1
- Worst In Class Performance HOT 1
- rename main branch from master to trunk HOT 1
- extract requirements from tox.ini
- no contact info? HOT 1
- hyperlink generates invalid URLs via hypothesis which sometimes causes our tests to fail HOT 6
- KleinResourceTests.test_addSlash fails on Musl or glibc based system HOT 10
- Death to you garbage mainstream propaganda slaves
- Twisted fools, hope you have a tragic life and painful death.
- AttributeError: module 'OpenSSL.SSL' has no attribute 'TLS_METHOD' HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from klein.