Name | pytagsup JSON |
Version |
0.1
JSON |
| download |
home_page | |
Summary | PyTags is a small XML/HTML construction templating library for Python, inspired by JavaTags. |
upload_time | 2024-03-10 14:41:34 |
maintainer | |
docs_url | None |
author | |
requires_python | >=3.11 |
license | MIT License Copyright (c) 2024 Manlio Modugno Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
keywords |
tags
html
templating
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
# Pytags
Pytags is a small XML/HTML construction templating library for Python, inspired by [JavaTags](https://github.com/manlioGit/javatags).
It can renders fragments like:
```python
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:
```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:
```python
pip install pytagsup
```
## Online converter
To convert html to Pytags format try [online converter](https://javatagsconverter.fly.dev).
## Usage
Import module `pytagsup.html` in your class.
```python
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.
```python
attr({'class': "navbar", 'style': "border: 0;"})
```
#### Dynamic
An attribute can be built fluently with `add` method, using key-value or `Attribute` overload
```python
(
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
```python
attr({'class': "navbar"})
.add({'class': "fa fa-up"})
.add({'style': "border: 0;"})
```
renders
```html
class='navbar fa fa-up' style='border: 0;'
```
An attribute can be modified with remove method, using key-value, Attribute overload or key
```python
attr({'class': ".some fa fa-up", 'xxx': "fa fa-up"})
.remove({'class': "fa-up"})
.remove({'xxx': "fa"})
.remove({'xxx': "fa-up"})
```
renders
```html
class='.some fa' xxx=''
```
```python
attr({'class': ".some fa fa-up", 'xxx': "fa fa-up"}).remove('class')
```
renders
```html
xxx='fa fa-up'
```
see [unit tests](https://github.com/manlioGit/ruby-tags/blob/master/test/ruby/attribute_test.rb) for other examples
### Layouts:
An example of page layout:
```python
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:
```python
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](https://www.w3.org/TR/html/syntax.html#writing-html-documents-elements)).
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](https://www.w3.org/TR/html).
To avoid built-in shadowing `builtins` module must be used, e.g.
```python
import builtins
div(*builtins.map(lambda t: p(text(t)), ['x', 'y', 'z']))
```
To render text use `text` method.
```python
text("aaa")
```
To render list of Elements you can use dummy `group` method or directly unpack argument lists
```python
...
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:
```python
...
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:
```python
(
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:
```python
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](https://github.com/manlioGit/ruby-tags/tree/master/test/ruby) 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](https://opensource.org/licenses/MIT).
Raw data
{
"_id": null,
"home_page": "",
"name": "pytagsup",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.11",
"maintainer_email": "",
"keywords": "tags,html,templating",
"author": "",
"author_email": "Manlio Modugno <manliomodugno@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/37/43/c4b4791ac69d1d9b464d4bf78f6463b01691ede7b64c8e5cd9dda0f5b0e9/pytagsup-0.1.tar.gz",
"platform": null,
"description": "# Pytags\n\nPytags is a small XML/HTML construction templating library for Python, inspired by [JavaTags](https://github.com/manlioGit/javatags).\n\nIt can renders fragments like:\n\n```python\nfrom pytagsup.html import *\n\nhtml5(attr({'lang': \"en\"}),\n head(\n meta(attr({'http-equiv': \"Content-Type\", 'content': \"text/html; charset=UTF-8\"})),\n title(text(\"title\")),\n link(attr({'href': \"xxx.css\", 'rel': \"stylesheet\"}))\n )\n).render()\n```\n\nin html:\n\n```html\n<!DOCTYPE html>\n<html lang='en'>\n <head>\n <meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/>\n <title>title</title>\n <link href='xxx.css' rel='stylesheet'/>\n </head>\n</html>\n```\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```python\npip install pytagsup\n```\n\n## Online converter\n\nTo convert html to Pytags format try [online converter](https://javatagsconverter.fly.dev).\n\n## Usage\n\nImport module `pytagsup.html` in your class.\n\n```python\nfrom pytagsup.html import *\n\nclass Layout: \n #...\n\n```\n### Attributes:\n\nYou have different ways to use attributes.\n\n#### Declarative\n\nUsing Python#Dictionary definition, i.e. `{'name': \"value\"}` in `attr` method. \n\n```python\nattr({'class': \"navbar\", 'style': \"border: 0;\"})\n```\n\n#### Dynamic\n\nAn attribute can be built fluently with `add` method, using key-value or `Attribute` overload\n\n```python\n(\n attr()\n .add({'class': \"fa fa-up\", 'xxx': \"show\"})\n .add({'style': \"border: 0;\"})\n)\n(\t\n attr()\n .add(attr({'class': \"navbar\"}))\n .add(attr({'style': \"border: 0;\"}))\n)\n```\n\n`add` method appends values if already defined for an attribute\n\n```python\nattr({'class': \"navbar\"})\n .add({'class': \"fa fa-up\"})\n .add({'style': \"border: 0;\"})\n```\n\nrenders\n\n```html\n class='navbar fa fa-up' style='border: 0;'\n```\n\nAn attribute can be modified with remove method, using key-value, Attribute overload or key\n\n```python\nattr({'class': \".some fa fa-up\", 'xxx': \"fa fa-up\"})\n .remove({'class': \"fa-up\"})\n .remove({'xxx': \"fa\"})\n .remove({'xxx': \"fa-up\"})\n```\n\nrenders\n\n```html\nclass='.some fa' xxx=''\n```\n\n```python\nattr({'class': \".some fa fa-up\", 'xxx': \"fa fa-up\"}).remove('class')\n```\n\nrenders\n\n```html\nxxx='fa fa-up'\n```\n\nsee [unit tests](https://github.com/manlioGit/ruby-tags/blob/master/test/ruby/attribute_test.rb) for other examples\n\n### Layouts:\n\nAn example of page layout:\n\n```python\nfrom pytagsup.html import *\n\nclass Layout:\n\n def __init__(self, title, body):\n self._title = title\n self._body = body\n \n def render(self):\n return (\n html5(\n head(\n meta(attr({'charset': \"utf-8\"})),\n meta(attr({'http-equiv': \"X-UA-Compatible\", 'content': \"IE=edge\"})),\n meta(attr({'name': \"viewport\", 'content': \"width=device-width, initial-scale=1\"})),\n title(text(self._title)),\n link(attr({'rel': \"stylesheet\", 'href': \"/css/bootstrap.min.css\"})),\n link(attr({'rel': \"stylesheet\", 'href': \"/css/app.css\"}))\n ),\n body(\n self._body,\n script(attr({'src': \"/js/jquery.min.js\"})),\n script(attr({'src': \"/js/bootstrap.min.js\"}))\n )\n ).render()\n )\n```\n\nAn example of table using reduce:\n\n```python\ndata = [{ 'th1': \"value1\", 'th2': \"value2\" }, { 'th1': \"value3\", 'th2': \"value4\" }]\nheader = data[0].keys()\n\ntable(attr({'class': \"table\"}),\n thead(\n reduce(\n lambda tr, h: tr.add(th(text(h))),\n header,\n tr()\n )\n ),\n reduce(\n lambda tbody, record: tbody.add(\n reduce(\n lambda row, x: row.add(td(text(record[x]))),\n header,\n tr()\n )\n ),\n data,\n tbody()\n )\n)\n\n```\n\n#### Element\n\nRuby-Tags defines Text, Void, NonVoid and Group elements (see [W3C Recommendation](https://www.w3.org/TR/html/syntax.html#writing-html-documents-elements)).\n\nEvery tag method (e.g. html5, body and so on) is defined as method using a Void or NonVoid element in accordance with [W3C Recommendation](https://www.w3.org/TR/html).\n\nTo avoid built-in shadowing `builtins` module must be used, e.g.\n\n```python\nimport builtins\n\ndiv(*builtins.map(lambda t: p(text(t)), ['x', 'y', 'z']))\n```\n\nTo render text use `text` method.\n\n```python\ntext(\"aaa\")\n```\n\nTo render list of Elements you can use dummy `group` method or directly unpack argument lists \n\n\n```python\n...\nl = builtins.map(lambda t: li(text(t)), ['a', 'b', 'c'])\nul(\n group(*l)\n)\n\n...\nul(\n group(*builtins.map(lambda x: li(text(x)), ['a', 'b', 'c']))\n)\n...\n\n```\n\nYou can also use `add` method to add children/sibling to a NonVoid/Void element respectively, for example:\n\n```python\n...\ng = group()\nfor x in ['a', 'b', 'c']:\n g.add(li(text(x)))\n...\n\t\nul = ul()\nfor x in ['a', 'b', 'c']:\n ul.add(li(text(x)))\n\n```\nOr in a builder/fluent syntax way:\n\n```python\n(\n ul()\n .add(li(text(\"item 1\")))\n .add(li(text(\"item 2\")))\n .add(li(text(\"item 3\")))\t\n) \n(\n div(attr({'class': \"xxx\"}))\n .add(span(text(\"content\")))\n .add(p(text(\"other content\")))\n)\n```\n\nElements are equal ignoring attribute order definition, for example:\n\n```python\ndef test_equality(self):\n div1 = NonVoid(\"div\", Attribute({'a': \"b\", 'c': \"d\"}))\n div2 = NonVoid(\"div\", Attribute({'c': \"d\", 'a': \"b\"}))\n\n assert div1 == div2\n```\n\nsee [unit tests](https://github.com/manlioGit/ruby-tags/tree/master/test/ruby) for other examples\n\n## Development\n\nAfter checking out the repo, run `pytest` to run the tests.\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/manlioGit/pytagsup.\n\n\n## License\n\nThe package is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n",
"bugtrack_url": null,
"license": "MIT License Copyright (c) 2024 Manlio Modugno Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.",
"summary": "PyTags is a small XML/HTML construction templating library for Python, inspired by JavaTags.",
"version": "0.1",
"project_urls": {
"Homepage": "https://github.com/manlioGit/pytagsup"
},
"split_keywords": [
"tags",
"html",
"templating"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "88dd6eb4bbc87642a396b6f43840dd7eb5055854bd6d0bd0a7459eedae18f64b",
"md5": "3a1a544c64724fbbcb505617b698465d",
"sha256": "57f69ce63c989b63220f3f566f017add1a0186bdc32f63e6eaf860bf2230294e"
},
"downloads": -1,
"filename": "pytagsup-0.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "3a1a544c64724fbbcb505617b698465d",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.11",
"size": 7289,
"upload_time": "2024-03-10T14:41:32",
"upload_time_iso_8601": "2024-03-10T14:41:32.338888Z",
"url": "https://files.pythonhosted.org/packages/88/dd/6eb4bbc87642a396b6f43840dd7eb5055854bd6d0bd0a7459eedae18f64b/pytagsup-0.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "3743c4b4791ac69d1d9b464d4bf78f6463b01691ede7b64c8e5cd9dda0f5b0e9",
"md5": "2acfada92ff642eb66715c1189b3c8d2",
"sha256": "6332610c8f719387d860377833475c7c27d53a3802d4c94bbe989477f312a804"
},
"downloads": -1,
"filename": "pytagsup-0.1.tar.gz",
"has_sig": false,
"md5_digest": "2acfada92ff642eb66715c1189b3c8d2",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.11",
"size": 9202,
"upload_time": "2024-03-10T14:41:34",
"upload_time_iso_8601": "2024-03-10T14:41:34.691794Z",
"url": "https://files.pythonhosted.org/packages/37/43/c4b4791ac69d1d9b464d4bf78f6463b01691ede7b64c8e5cd9dda0f5b0e9/pytagsup-0.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-03-10 14:41:34",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "manlioGit",
"github_project": "pytagsup",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "pytagsup"
}