echo a77829aad7 | ||
---|---|---|
cuddly | ||
samples | ||
.gitignore | ||
LICENSE | ||
README.md | ||
pyproject.toml |
README.md
Cuddly
Generate HTML and PDF from KDL structed data.
Installation
git clone https://git.bksp.space/hannaeko/cuddly
cd cuddly
python -m venv env
env/bin/pip install .
Usage
Example
Generating a PDF:
env/bin/cuddly --template samples/cv/cv.template.html --input samples/cv.kdl --output samples/cv.pdf
Generating a HTML file
env/bin/cuddly --template samples/cv/cv.template.html --input samples/cv.kdl --output samples/cv.html
Template usage
The template language used is Jinja, source template need to be a single HTML template file.
Base URL
When generating the PDF the base URL is set to the source template directory. All relative links to other resources (for example CSS and images) must be relative to that directory.
Accessing nodes values and attributes
Nodes are available as global variables in the template. The rendered value of a node is the first value that has been assigned to the node. This value can also be accessed using the value
property. The list of values can be accessed using the values
property.
my_node "something" "other thing"
{{ my_node }}
{{ my_node.value }}
{{ my_node.values | join(', ')}}
renders to
something
something
something, other thing
Accessing children nodes can be done using properties of the children names.
my_node {
other_node "test"
}
{{ my_node.other_node.value }}
renders to
test
If a node has multiple children of a same node type, then directly accessing the children properties will fail, a loop will be needed. Note that, on the other hand, looping on the children always work, even if there is only one child of the given type.
my_node {
other_node "first"
other_node "second"
}
{% for node in my_node.other_node %}
{{ node.value }}
{% endofr %}
renders to
first
second
Attributes of a node can be accessed through the attributes
property:
my_node version=42 "something"
{{ my_node.attributes.version }}
renders to
42
Templating nodes
Node specific templates can be defined in the components
element in the HTML template file. Nodes can then be rendered using those micro-templates using the render
filter.
The context of the micro-template is the node being rendered. As such, children and properties of that node are in the global scope.
menu "Midnight meal" price="10 €" {
dish name="Tomato soup" "Fancy tomato soup with a slice of bread"
dish name="Banana bread" "Amazing banana bread with a scoop of icecream"
}
<!DOCTYPE html>
<html lang="{{ lang }}">
<head>
<meta charset="UTF-8">
</head>
<components>
<menu>
<h1>{{ value }}</h1>
<dl>
<dt>Price</dt>
<dd>{{ attributes.prices }}</dd>
</dl>
<dl>
{% for dish in dish %}
{{ dish | render }}
{% endfor %}
</dl>
</menu>
<dish>
<div>
<dt>{{ attribute.name }}</dt>
<dd>{{ value }}</dd>
</div>
</dish>
</components>
<body>
{{ menu | render }}
</body>
Samples
samples/cv/cv.template.html
: Template to generate a CV, seesamples/cv.kdl
for the input data.