Skip to main content

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

This version

0.1

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pytagsup-0.1.tar.gz (9.2 kB view details)

Uploaded Source

Built Distribution

pytagsup-0.1-py3-none-any.whl (7.3 kB view details)

Uploaded Python 3

File details

Details for the file pytagsup-0.1.tar.gz.

File metadata

  • Download URL: pytagsup-0.1.tar.gz
  • Upload date:
  • Size: 9.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.0.0 CPython/3.11.6

File hashes

Hashes for pytagsup-0.1.tar.gz
Algorithm Hash digest
SHA256 6332610c8f719387d860377833475c7c27d53a3802d4c94bbe989477f312a804
MD5 2acfada92ff642eb66715c1189b3c8d2
BLAKE2b-256 3743c4b4791ac69d1d9b464d4bf78f6463b01691ede7b64c8e5cd9dda0f5b0e9

See more details on using hashes here.

File details

Details for the file pytagsup-0.1-py3-none-any.whl.

File metadata

  • Download URL: pytagsup-0.1-py3-none-any.whl
  • Upload date:
  • Size: 7.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.0.0 CPython/3.11.6

File hashes

Hashes for pytagsup-0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 57f69ce63c989b63220f3f566f017add1a0186bdc32f63e6eaf860bf2230294e
MD5 3a1a544c64724fbbcb505617b698465d
BLAKE2b-256 88dd6eb4bbc87642a396b6f43840dd7eb5055854bd6d0bd0a7459eedae18f64b

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page