PyTags is a small XML/HTML construction templating library for Python, inspired by JavaTags.
Project description
Pytags
Pytags is a small XML/HTML construction templating library for Python, inspired by JavaTags.
It can renders fragments like:
from pytagsup.html import *
html5(attr({'lang': "en"}),
head(
meta(attr({'http-equiv': "Content-Type", 'content': "text/html; charset=UTF-8"})),
title(text("title")),
link(attr({'href': "xxx.css", 'rel': "stylesheet"}))
)
).render()
in html:
<!DOCTYPE html>
<html lang='en'>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/>
<title>title</title>
<link href='xxx.css' rel='stylesheet'/>
</head>
</html>
Installation
Add this line to your application's Gemfile:
pip install pytagsup
Online converter
To convert html to Pytags format try online converter.
Usage
Import module pytagsup.html in your class.
from pytagsup.html import *
class Layout:
#...
Attributes:
You have different ways to use attributes.
Declarative
Using Python#Dictionary definition, i.e. {'name': "value"} in attr method.
attr({'class': "navbar", 'style': "border: 0;"})
Dynamic
An attribute can be built fluently with add method, using key-value or Attribute overload
(
attr()
.add({'class': "fa fa-up", 'xxx': "show"})
.add({'style': "border: 0;"})
)
(
attr()
.add(attr({'class': "navbar"}))
.add(attr({'style': "border: 0;"}))
)
add method appends values if already defined for an attribute
attr({'class': "navbar"})
.add({'class': "fa fa-up"})
.add({'style': "border: 0;"})
renders
class='navbar fa fa-up' style='border: 0;'
An attribute can be modified with remove method, using key-value, Attribute overload or key
attr({'class': ".some fa fa-up", 'xxx': "fa fa-up"})
.remove({'class': "fa-up"})
.remove({'xxx': "fa"})
.remove({'xxx': "fa-up"})
renders
class='.some fa' xxx=''
attr({'class': ".some fa fa-up", 'xxx': "fa fa-up"}).remove('class')
renders
xxx='fa fa-up'
see unit tests for other examples
Layouts:
An example of page layout:
from pytagsup.html import *
class Layout:
def __init__(self, title, body):
self._title = title
self._body = body
def render(self):
return (
html5(
head(
meta(attr({'charset': "utf-8"})),
meta(attr({'http-equiv': "X-UA-Compatible", 'content': "IE=edge"})),
meta(attr({'name': "viewport", 'content': "width=device-width, initial-scale=1"})),
title(text(self._title)),
link(attr({'rel': "stylesheet", 'href': "/css/bootstrap.min.css"})),
link(attr({'rel': "stylesheet", 'href': "/css/app.css"}))
),
body(
self._body,
script(attr({'src': "/js/jquery.min.js"})),
script(attr({'src': "/js/bootstrap.min.js"}))
)
).render()
)
An example of table using reduce:
data = [{ 'th1': "value1", 'th2': "value2" }, { 'th1': "value3", 'th2': "value4" }]
header = data[0].keys()
table(attr({'class': "table"}),
thead(
reduce(
lambda tr, h: tr.add(th(text(h))),
header,
tr()
)
),
reduce(
lambda tbody, record: tbody.add(
reduce(
lambda row, x: row.add(td(text(record[x]))),
header,
tr()
)
),
data,
tbody()
)
)
Element
Ruby-Tags defines Text, Void, NonVoid and Group elements (see W3C Recommendation).
Every tag method (e.g. html5, body and so on) is defined as method using a Void or NonVoid element in accordance with W3C Recommendation.
To avoid built-in shadowing builtins module must be used, e.g.
import builtins
div(*builtins.map(lambda t: p(text(t)), ['x', 'y', 'z']))
To render text use text method.
text("aaa")
To render list of Elements you can use dummy group method or directly unpack argument lists
...
l = builtins.map(lambda t: li(text(t)), ['a', 'b', 'c'])
ul(
group(*l)
)
...
ul(
group(*builtins.map(lambda x: li(text(x)), ['a', 'b', 'c']))
)
...
You can also use add method to add children/sibling to a NonVoid/Void element respectively, for example:
...
g = group()
for x in ['a', 'b', 'c']:
g.add(li(text(x)))
...
ul = ul()
for x in ['a', 'b', 'c']:
ul.add(li(text(x)))
Or in a builder/fluent syntax way:
(
ul()
.add(li(text("item 1")))
.add(li(text("item 2")))
.add(li(text("item 3")))
)
(
div(attr({'class': "xxx"}))
.add(span(text("content")))
.add(p(text("other content")))
)
Elements are equal ignoring attribute order definition, for example:
def test_equality(self):
div1 = NonVoid("div", Attribute({'a': "b", 'c': "d"}))
div2 = NonVoid("div", Attribute({'c': "d", 'a': "b"}))
assert div1 == div2
see unit tests for other examples
Development
After checking out the repo, run pytest to run the tests.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/manlioGit/pytagsup.
License
The package is available as open source under the terms of the MIT License.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters