Skip to main content

CSS & HTML on Python Easily

Project description

Chope

CSS & HTML on Python Easily.

PyPI Pepy Total Downlods GitHub GitHub Workflow Status (with branch) PyPI - Python Version

Chope is a library that aims to provide a HTML and CSS domain-specific language (DSL) for Python. It draws inspiration from Clojure's Hiccup and JavaScript's Emotion.

Install

Chope can be installed through pip.

pip install chope

Syntax

Here is a basic example of Chope syntax:

from chope import *
from chope.css import *

page = html[
    head[
        style[
            Css[
                'body': dict(
                    background_color='linen',
                    font_size=pt/12
                ),
                '.inner-div': dict(
                    color='maroon',
                    margin_left=px/40
                )
            ]
        ]
    ],
    body[
        h1['Title'],
        div(class_='outer-div')[
            div(class_='inner-div')[
                'Some content.'
            ]
        ]
    ]
]

HTML

Declaring an element is as simple as this:

# <div>content</div>

div['content']

Element attributes can be specified like so:

# <div id="my-id" class="my-class your-class">content</div>

div(id='my-id', class_='my-class your-class')['content']

Notice the _ suffix in the class_ attribute. This suffix is necessary for any attribute names that clashes with any Python keyword.

You can also define id and class using CSS selector syntax:

# <div id="my-id" class="my-class your-class" title="Title">content</div>

div('#my-id.my-class.your-class', title='Title')['content']

Iterables can be used to generate a sequence of elements in the body of an element.

# <ul><li>0</li><li>1</li><li>2</li></ul>

ul[
    (li[str(i)] for i in range(3))
]

Creating custom elements

If you want to create a custom element with a custom tag, simply inherit from the Element class.

from chope import Element


class custom(Element):  ## class name will be used as tag name during rendering
    pass


custom['some content.']  ## <custom>some content.</custom>

Normally, you don't need to override any method of Element, but if you want to change how your element is rendered, you can override the render() method.

CSS

The CSS syntax in Chope is simply a mapping between CSS selector strings and declarations dictionaries.

Here's how a simple CSS stylesheet looks like in Chope:

'''
h1 {
    color: blue;
}

.my-class {
    background-color: linen;
    text-align: center;
}
'''

Css[
    'h1': dict(
        color='blue'
    ),
    '.my-class': dict(
        background_color='linen',
        text_align='center'
    )
]

# OR

Css[
    'h1': {
        'color': 'blue'
    },
    '.my-class': {
        'background-color': 'linen',
        'text-align': 'center'
    }
]

When you do declarations using the dict constructor, any _ will be converted to - automatically.

If your attribute name actually contains an _, declare using dictionary literal instead.

Units

Declaring size properties is very simple:

'''
.my-class {
    font-size: 14px;
    margin: 20%;
}
'''

Css[
    '.my-class': dict(
        font_size=px/14,
        margin=percent/20
    )
]

Chope supports standard HTML units. (e.g.em, rem, pt, etc.)

To set properties with multiple values, simply pass an iterable or a string.

'''
.my-class {
    padding: 58px 0 0;
}
'''

Css[
    '.my-class': dict(
        padding=(px/58, 0, 0)
    )
]

# OR

Css[
    '.my-class': dict(
        padding='58px 0 0'
    )
]

Render

Once you are done defining your CSS and HTML, you can render them into string using the render() method.

>>> page = html[
    head[
        style[
            Css[
                '.item': dict(font_size=px/14)
            ]
        ]
    ],
    body[
        div('#my-item.item')['My content.']
    ]
]
>>> print(page.render())
'<html>
  <head>
    <style>
      .item {
        font-size: 14px;
      }
    </style>
  </head>
  <body>
    <div id="my-item" class="item">
      My content.
    </div>
  </body>
</html>'

By default, render() will add indentations with 2 spaces. You can modify this using the indent keyword argument.

>>> print(page.render(indent=4))
'<html>
    <head>
        <style>
            .item {
                font-size: 14px;
            }
        </style>
    </head>
    <body>
        <div id="my-item" class="item">
            My content.
        </div>
    </body>
</html>'
>>> print(page.render(indent=0))  ## render flat string
'<html><head><style>.item {font-size: 14px;}</style></head><body><div id="my-item" class="item">My content.</div></body></html>'

CSS objects can also be rendered the same way.

>>> css = Css[
    'h1': dict(font_size=px/14),
    '.my-class': dict(
        color='blue',
        padding=(0,0,px/20)
    )
]
>>> print(css.render())
'h1 {
    font-size: 14px;
}

.my-class {
    color: blue;
    padding: 0 0 20px;
}'

Variable

If you'd like to build a HTML template, you can do so using the Var object.

from chope import *
from chope.variable import Var

template = html[
    div[Var('my-content')]
]

final_html = template.set_vars({'my-content': 'This is my content.'})

print(final_html.render(indent=0))  ## <html><div>This is my content.</div></html>

A variable can have a default value.

>>> print(div[Var('content', 'This is default content.')].render(indent=0))
<div>This is default content.</div>

Variable value can be set to an element.

>>> content = div[Var('inner')]
>>> new_content = content.set_vars({'inner': div['This is inner content.']})
>>> print(new_content.render())
<div>
  <div>
    This is inner content.
  </div>
</div>

Var works in an element attribute as well.

>>> content = div(name=Var('name'))['My content.']
>>> new_content = content.set_vars({'name': 'my-content'})
>>> print(new_content.render())
<div name="my-content">
  My content.
</div>

You can use Var in CSS too.

>>> css = Css[
    # CSS rule as a variable
    'h1': dict(font_size=Var('h1.font-size')),

    # CSS declaration as a variable
    '.my-class': Var('my-class')
]
>>> new_css = css.set_vars({'h1.font-size': px/1, 'my-class': {'color': 'blue'}})
>>> print(new_css.render())
h1 {
  font-size: 1px;
}

.my-class {
  color: blue;
}

The set of all variable names in an element/CSS can be retrieved using the get_vars() method.

>>> template = html[
    style[
        Css[
            'h1': dict(font_size=Var('css.h1.font-size'))
        ]
    ],
    div[
        Var('main-content'),
        div[
            Var('inner-content')
        ]
    ]
]
>>> print(template.get_vars())
{'main-content', 'inner-content', 'css.h1.font-size'}

Project details


Download files

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

Source Distribution

chope-0.3.0.tar.gz (14.4 kB view details)

Uploaded Source

Built Distribution

chope-0.3.0-py3-none-any.whl (10.9 kB view details)

Uploaded Python 3

File details

Details for the file chope-0.3.0.tar.gz.

File metadata

  • Download URL: chope-0.3.0.tar.gz
  • Upload date:
  • Size: 14.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.16

File hashes

Hashes for chope-0.3.0.tar.gz
Algorithm Hash digest
SHA256 6b6bbeda86c49d45a6ae0d82e66f81107453b1307e60fc5f16113795e969cd0a
MD5 c950322ffbaf90974997a656caaf0222
BLAKE2b-256 e2cc69bdc303288d54c9f64a801ae2d4c4317bd860e19ca7c39af5c1184e4ff7

See more details on using hashes here.

File details

Details for the file chope-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: chope-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 10.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.16

File hashes

Hashes for chope-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6fa33d83021d58001dbd6f96538e62ae5ef1b2aee7d41fb9c92e393ae45866b7
MD5 03f639946f578340719f3f62e986487a
BLAKE2b-256 77f9f85b15ea8488ec78707f61500626253e35353f7cfde313ee92478f282f3b

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