Skip to main content

Generate html with python 3. DOM API, Javascript API and more...

Project description

domonic: generate html with python 3!
domonic
Generate html with python 3! (and much more)

PyPI version Downloads Python version Build status Python package

Contains several evolving packages: (but by no means are any of them complete)

html : Generate html with python 3 😎
dom : DOM API in python 3 😲
javascript : js API in python 3 😳
dQuery - NEW. Recently started. utils for querying domonic. (alt + 0 for the º symbol)
• terminal || cmd : call terminal commands with python3 😱 (see at the end)
• JSON : utils for loading / decorating / transforming
• SVG : Generate svg using python (untested)
• aframe || x3d tags : auto generate 3d worlds with aframe. (see examples folder)

See the docs/code for more features... https://domonic.readthedocs.io/

or examples in the repo...

HTML Templating with Python 3

from domonic.html import *
print(html(body(h1('Hello, World!'))))
<html><body><h1>Hello, World!</h1></body></html>

install

python3 -m pip install domonic

or if you had it before upgrade:

python3 -m pip install domonic --upgrade

attributes

prepend attributes with an underscore ( avoids clashing with python keywords )

test = label(_class='classname', _for="someinput")
print(test)
<label class="classname" for="someinput"></label>

rendering

you can just cast str() on any element to render it.

el_string = str(div())
print(el_string)

there's also a render method that takes 2 parameters, some domonic and an optional output file.

page = div(span('Hello World'))
render(page, 'index.html')

So you can build your own static site generator using python simply by serialising a dataset into pyml.

decorators

You can use decorators to wrap elements around function results

from domonic.decorators import el

@el(html, True)
@el(body)
@el(div)
def test():
    return 'hi!'

print(test())
# <html><body><div>hi!</div></body></html>

# returns pyml objects so call str to render
assert str(test()) == '<html><body><div>hi!</div></body></html>'

It returns the tag object by default. You can pass True as a second param to the decorator to return a rendered string instead. Also accepts strings as first param i.e. custom tags.

data-tags

python doesn't allow hyphens in parameter names. so use variable keyword argument syntax for custom data-tags

div("test", **{"_data-test":"test"} )

DOM

createElement

to create your own elements use the DOM API

from domonic.dom import *

site = html()
el = document.createElement('myelement')
site.appendChild(el)
print(site)

There's an evolving DOM. Check code/docs to see what's currently implemented. i.e

mysite.querySelectorAll('button')

javascript

There is a javascript package that mimics the js API:

from domonic.javascript import Math
print(Math.random())

from domonic.javascript import Array
myArr=Array(1,2,3)
print(myArr.splice(1))

from domonic.javascript import URL
url = URL('https://somesite.com/blog/article-one#some-hash')
print(url.protocol)
print(url.host)
print(url.pathname)
print(url.hash)

# from domonic.javascript import Global
# Global.decodeURIComponent(...
# Global.encodeComponent(...

# from domonic.javascript import Date
# etc..

You can use setInterval and clearInterval with params

x=0

def hi(inc):
    global x
    x = x+inc
    print(x)

test = window.setInterval(hi, 1000, 2)
import time
time.sleep(5)
window.clearInterval(test)
print(f"Final value of x:{x}")

a-tags inherits from URL:

from domonic.html import *

atag = a(_href="https://somesite.com:8000/blog/article-one#some-hash")
print('href:',atag.href)
print('protocol:',atag.protocol)
print('port:',atag.port)

atag.protocol = "http"
atag.port = 8983
print(atag)

For writing and using regular javascript you can load from a source...

script(_src="/docs/5.0/dist/js/bootstrap.bundle.min.js", _integrity="sha384-1234", _crossorigin="anonymous"),

or do inline js by opening triple quotes...

script("""
let itbe = ""
"""),

Styling

Styling is supported. Styles get passed to the style tag on render...

mytag = div("hi", _id="test")
mytag.style.backgroundColor = "black"
mytag.style.fontSize = "12px"
print(mytag)
# <div id="test" style="background-color:black;font-size:12px;">hi</div>

To use css use a link tag as you usually would...

link(_href="styles.css", _rel="stylesheet"),

or use triple quotes to open style tag...

style("""
.placeholder-img {
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}
"""),

JSON (utils)

decorate any function that returns python objects to return json instead

from domonic.JSON import *

@return_json
def somefunc():
    myObj = {"hi":[1,2,3]}
    return myObj

print( somefunc() )
print( is_json(somefunc()) )

convert json arrays into html tables...

from domonic.JSON import *

# i.e. containting flat json array of dicts... [{"id":"01","name": "some item"},{"id":"02","name": "some other item"}]

json_data = JSON.parse_file('somefile.json')
mytable = JSON.tablify(json_data)
print(mytable)

convert json arrays into csv files...

from domonic.JSON import *

json_data = JSON.parse_file('somefile.json')
JSON.csvify(json_data, 'data.csv')

convert csv files to json...

from domonic.JSON import *

json_data =JSON.csv2json("data.csv")
print(json_data)

more to come...

SVG (untested)

Well I tested circle and that works... But should be fine :)

All tags extend 'Node' and 'tag'. So will have DOM and magic methods available to them. see the docs.

        circ = svg(
            circle(_cx="50", _cy="50", _r="40", _stroke="green", **{"_stroke-width": "4"}, _fill="yellow"),
            _width="100", _height="100",
        )
        mysvg = svg()
        mysvg.appendChild(circ / 10)
        print(mysvg)

Tweening

You can tween values with the tween library:

from domonic.lerpy.easing import *
from domonic.lerpy.tween import *

someObj = {'x':0,'y':0,'z':0}
twn = Tween( someObj, { 'x':10, 'y':5, 'z':3 }, 6, Linear.easeIn )
twn.start()

aframe / x3d

to use 3d tags can be used if you import the js

from domonic.html import *
from domonic.aframe import *
from domonic.CDN import *

_scene = scene(
      box(_position="-1 0.5 -3", _rotation="0 45 0", _color="#4CC3D9"),
      sphere(_position="0 1.25 -5", _radius="1.25", _color="#EF2D5E"),
      cylinder(_position="1 0.75 -3", _radius="0.5", _height="1.5", _color="#FFC65D"),
      plane(_position="0 0 -4", _rotation="-90 0 0", _width="4", _height="4", _color="#7BC8A4"),
      sky(_color="#ECECEC")
    )

_webpage = html(head(),body(
    script(_src=CDN_JS.AFRAME_1_2), # < NOTICE you need to import aframe to use it
    str(_scene)
    )
)

render( _webpage, 'hello.html' )

dQuery (NEW)

dQuery uses the º symbol (alt+0).

    d = html(head(body(li(_class='things'), div(_id="test"))))

    º(d) # you need to init a dom first. i.e. a html element

    # now you can use it
    print( º('#test') )
    print( º('.things') )
    a = º('<div class="test2"></div>')
    print( a )

    b = º('#test').append(a)
    print(b)

Only recently started so check to see what's implemented.

terminal

There is a command line package that can call bash/unix/posix and other apps on the command line:
This package only works on nix systems as it effectively just passes stuff off to subprocess.

from domonic.terminal import *

print(ls())
print(ls("-al"))
print(ls("../"))
print(pwd())
print(mkdir('somedir'))
print(touch('somefile'))
print(git('status'))

for file in ls( "-al" ):
    print("Line : ", file)

for f in ls():
    try:
        print(f)
        print(cat(f))
    except Exception as e:
        pass

for i, l in enumerate(cat('LICENSE.txt')):
    print(i,l)

print(man("ls"))
print(echo('test'))
print(df())
print(du())

for thing in du():
    print(thing)

print(find('.'))
# print(ping('eventual.technology'))# < TODO - need to strean output
print(cowsay('moo'))
print(wget('eventual.technology'))
print(date())
print(cal())

or just run arbitrary commands...

from domonic.terminal import command
command.run("echo hi")

Take a look at the code in 'terminal.py' to see all the commands as there's loads. (Disclaimer: not all tested.)

Windows users can use now use cmd.

from domonic.cmd import *
print(dir())
print(dir("..\\")) 

DOCS

https://domonic.readthedocs.io/

notes on templating

while you can create a div with content like :

div("some content")

python doesn't allow named params before unamed ones. So you can't do this:

div(_class="container", p("Some content") )

or it will complain the params are in the wrong order. You have to instead put content before attributes:

div( p("Some content"), _class="container")

which is annoying when a div gets long.

You can get around this by using 'html' which is available on every Element:

div( _class="container" ).html("Some content")

This is NOT like jQuery html func that returns just the inner content. use innerHTML for that.

It is used specifically for rendering.

Common Errors

If templates are typed incorrectly they will not work.

There's a small learning curve getting .pyml templates correct. Usually (1) a missing comma between tags, (2) an underscore missing on an attribute or (3) params in the wrong order. Use this reference when starting out as a reminder when you get an error.

Here are the 4 solutions to those common errors when creating large templates... ( i.e. see bootstrap5 examples in test_domonic.py )

IndexError: list index out of range - You most likely didn't put a underscore on an attribute.

SyntaxError: invalid syntax - You are Missing a comma between attributes

SyntaxError: positional argument follows keyword argument - You have to pass attributes LAST. and strings and objects first. see notes on templating above

TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'dict' - You are Missing a comma between attributes. before the **{}

TODO - catch these errors and raise a friendly custom ParseError that tells you what to fix

CLI

There's a few args you can pass to domonic on the command line to help you out.

To launch the docs for a quick reference to the APIs use:

python3 -m domonic -h

This command will attempt to generate a template from a webpage. (only simple pages for now)

python3 -m domonic -d http://eventual.technology

Then you can edit/tweak it to get what you need and build new components quicker.

EXAMPLE PROJECTS

A browser based file browser. Working example of how components can work: https://github.com/byteface/Blueberry/

A cron viewer: https://github.com/byteface/ezcron/

A basic game: https://github.com/byteface/bombdisposer/

docs: https://domonic.readthedocs.io/

There's also several useage examples in the repo so pull and have a look.

Join-In

Feel free to contribute if you find it useful.

Email me, message me directly if you like or create a discussion on here.

If there are any methods you want that are missing or not complete yet or you think you can help make it better just update the code and send a pull request.

I'll merge and releaese asap.

In the repo there's a requirements-dev.txt which is mostly the libs used in the examples.

requirements.txt are the libs used for packaging just the lib.

running examples

. venv/bin/activate
pip install -r requirements-dev.txt
cd examples
python lifecalendar.py

run tests

There are tests used during dev. They are useful as code examples and to see what still needs doing.

See Makefile to run all tests:

make test

or to test a single function:

python -m unittest tests.test_javascript.domonicTestCase.test_javascript_array
python -m unittest tests.test_dQuery.domonicTestCase.test_dQuery_addClass
python -m unittest tests.test_geom.domonicTestCase.test_vec2

python3 -m unittest tests.test_cmd.domonicTestCase.test_cmd_dir

or to test a whole module

python -m unittest tests.test_html
python -m unittest tests.test_CDN

to see coverage

coverage run -m unittest discover tests/
coverage report

rebuild docs

See Makefile:

. venv/bin/activate
cd docs
make html

Disclaimer

There's several more widely supported libraries doing HTML generation, DOM reading/manipulation, terminal wrappers etc. Maybe use one of those for production due to strictness and support.

This is more of a fast prototyping library.

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

domonic-0.4.0.tar.gz (198.8 kB view details)

Uploaded Source

Built Distribution

domonic-0.4.0-py3-none-any.whl (170.3 kB view details)

Uploaded Python 3

File details

Details for the file domonic-0.4.0.tar.gz.

File metadata

  • Download URL: domonic-0.4.0.tar.gz
  • Upload date:
  • Size: 198.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.23.0 setuptools/49.2.0 requests-toolbelt/0.9.1 tqdm/4.48.2 CPython/3.8.5

File hashes

Hashes for domonic-0.4.0.tar.gz
Algorithm Hash digest
SHA256 82dd7746820b28e0ca2dbe5dad68e8b2f78f1d8463914c681f06dd26ec73e6a2
MD5 22ca158ba99e56556ea1acf7a4f87238
BLAKE2b-256 2116b48be5e76a1a940d87345b8bfc285ef083bc305d1e180858927ce4a0264f

See more details on using hashes here.

File details

Details for the file domonic-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: domonic-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 170.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.23.0 setuptools/49.2.0 requests-toolbelt/0.9.1 tqdm/4.48.2 CPython/3.8.5

File hashes

Hashes for domonic-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1c9b0022a69e133748a28a6d4995a5d78ba2e08d3ce689dcf8b29129a8193b0b
MD5 6282b98419d86f3e5739f5962f63572c
BLAKE2b-256 d78803a1faa8376558928bc3e8a7369419046863d6deee3dabd0b3fea90ed495

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