Templating utilities
Project description
Sonotoria
Sonotoria is a library designed to provide features helping with templating and handling yaml files.
Jinja templating
Sonotoria provides some functions to make the use of jinja2 templating easier.
Note that all the functions presented in this section have the following optional arguments:
- context: A dictionary used as context for the templating
- filters: A dictionary of filters usable during the templating
- tests: A dictionary of tests usable during the templating
Example:
// Context
{'key': 'value'} -> {{ test }} -> value
// Filters
{'twotimes': lambda v: v*2} -> {{ test | twotimes }} -> valuevalue
// Tests
{'big': lambda v: len(v) > 10} -> {{ test is big }} -> false
template_string
Shortcut for templating strings:
>>> from sonotoria import jinja
>>> jinja.template_string('Hello {{ hello }}!', context={'hello': 'world'})
Hello world!
template_file
Shortcut for templating files:
>>> from sonotoria import jinja
>>> jinja.template_file('myfile.j2', 'myfile')
template_folder
Shortcut for templating folders:
>>> from sonotoria import jinja
>>> jinja.template_folder('myfolder', 'mytemplatedfolder')
Note that the folder can contain an optional template configuration in a .template
folder. Here you can add config file config.yaml
.
The config file should like this:
---
default: # optional default values for the context
myvar: myvalue
exclude: # an optional list of file path to ignore
- .git
template: # use this part to provide information regarding the templating of the folders and files' names
loop: # The loop section concerns files or folder that should be created using a list, one file/folder will be created for each element of the list
- folder: myfolder # use file for a file, folder for a folder
var: folders # the variable from the context that contains the list (required)
item: folder # the name of the variable in the cotext used to hold the list elements' values
# If the var name end with an 's', then the item is automatically defined with this name without the s
# Therefore the 'item' definition here would have been added by default
transform: my_{{ folder }}_looped # explicit how to transform the folder name, by default it will be named using the item value
loop: # when looping a folder, you can also loop elements within the folder
- file: myfile
loop: # looping is obviously not available for a file, this will result in a configuration error
...
filters: # You can choose filters to apply !on the list! before the templating (filters have the least priority)
- myfilter
when: # You can choose test to filter out !element of the list! before the templating
- mytest
excluded_values: # You can also exclude values directly (excluded_values have the highest priority)
- myvalue
rename: # The rename section is for renaming file or folder without looping (you can create create rename section in looped folder as well)
- folder: myotherfolder
var: myvar # When renaming, using var is a shortcut for "transform: {{ myvar }}"
transform: my_{{ folders[0] | single }} # The transform is used to define how to rename the folder/file if var is also defined a warning will be logged and var will be ignored
# As we can see in this transform, you can use filters and use typical operations such as the dot and the brackets
loop: # Once again, when renaming a folder you can use a loop for the elements inside the folder
rename: # ... or a rename
- folder: dontchangeme # You can also not change a folder just to perform actions on the element inside
loop:
- file: changeme
var: changes
You can also create a default.yaml
file to hold default values outside of the configuration file. You can use both the default section and the default file. In that case, the default section (in the config file) will have the priority if a variable is defined twice. (And variables passed to the context of the function have obviously the highest priority). You can also create a vars.yaml
to create variables after the context is loaded and use the context in it (using jinja syntax).
Finally you may also add a filters.py
and/or a tests.py
to add filters and tests that will be loading before templating. All they need is to respectively have a get_filters
and get_tests
function. Those function must return dictionaries with the filters/tests.
Loading Yaml
Sonotoria lets you load a yaml with variables using jinja2 syntax:
Examples
From a file
Given the file:
# test.yml
---
param: value
param2: {{ param }}
You can load the data:
>>> from sonotoria import jaml
>>> jaml.load('test.yml')
{'param': 'value', 'param2': 'value'}
From a string
You can also load a string directly:
>>> from sonotoria import jaml
>>> jaml.loads('---\nparam: value\nparam2: {{ param }}')
{'param': 'value', 'param2': 'value'}
Using context
Given the file:
# test.yml
---
param2: {{ param }}
You can load the data:
>>> from sonotoria import jaml
>>> jaml.load('test.yml', context={'param': 12})
{'param2': 12}
Using filters
Given the file:
# test.yml
---
param: value
param2: {{ param | doubled }}
You can load the data:
>>> from sonotoria import jaml
>>> jaml.load('test.yml', filters={'doubled': lambda s: s*2})
{'param': 'value', 'param2': 'valuevalue'}
Using tests
Given the file:
# test.yml
---
param: value
param2: {{ param is number }}
You can load the data:
>>> from sonotoria import jaml
>>> jaml.load('test.yml', tests={'number': lambda s: s.isdigit()})
{'param': 'value', 'param2': False}
Using objects
Given the file:
# test.yml
--- !stuff
param: value
param2: {{ param }}
You can load the data:
>>> from sonotoria import jaml
>>> class Stuff:
.... pass
>>> my_stuff = jaml.load('test.yml', types={'stuff': Stuff})
>>> my_stuff.param
value
>>> my_stuff.param2
value
You can add tests, filters and types:
Extractor
Sonotoria lets you extract data from a file using a jinja2 template.
Example
Given this input file:
That is a description
:param test: Looks like a test variable, huh
:param lol: This might be a fun variable
:param plop: Plop might just be the next best variable name
:return: Pretty much nothing, sadly
And this template file:
{{ description }}
{% for param, desc in params.items() %}
:param {{ param }}: {{ desc }}
{% endfor %}{% if return_given %}
:return: {{ return }}{% endif %}{% if rtype_given %}
:rtype: {{ rtype }}{% endif %}
You can extract data this way:
>>> import sonotoria
>>> sonotoria.extract('template.file', 'input.file')
{
'description': 'That is a description',
'params': {
'test': 'Looks like a test variable, huh',
'lol': 'This might be a fun variable',
'plop': 'Plop might just be the next best variable name'
},
'return': 'Pretty much nothing, sadly',
'rtype': None,
'return_given': True,
'rtype_given': False
}
Contributors
- Emmanuel Pluot (aka. Neomyte)
Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased]
[0.3.7] - 2022-12-13
Fixed
- Fix file included in other file name not being handled
[0.3.6] - 2022-11-24
Changed
- Ensure folders are created when skipping a template
[0.3.5] - 2022-11-24
Changed
- Files with wrong encoding skipped when templating a folder
[0.3.4] - 2022-10-22
Changed
- Fix excluded like files being wrongly excluded
[0.3.3] - 2022-10-20
Changed
- Handle python 3.8
[0.3.2] - 2021-04-25
Changed
- Fixed template_file failing when no subfolders
[0.3.1] - 2021-04-21
Changed
- Fixed template_folder failing when no config is found
- Fixed template folder failing when folder name not templated
- Fixed template folder not templating when no config found
[0.3.0] - 2021-04-15
Added
- Local higher priority vars file for folder templating
Changed
- yaml module renamed jaml (!BREAKING)
[0.2.1] - 2021-04-15
Changed
- Fix python-benedict dependency
[0.2.0] - 2021-04-15
Added
- Add doc to template_string
- Add template_file to jinja
- Add template_folder to jinja
Changed
- Enhanced dumping
- Fixed CI not updating packages
[0.1.9] - 2021-11-30
Changed
- fixed dump (again :p)
[0.1.8] - 2021-11-30
Changed
- fixed dump
[0.1.7] - 2021-11-30
Added
- possibility to give a context to the yaml loader
[0.1.6] - 2021-10-24
Changed
- removed print statements
[0.1.5] - 2021-10-24
Added
- Add dumpers for yaml
Changed
- fixed readme
[0.1.4] - 2021-10-24
Changed
- fixed readme
[0.1.3] - 2021-10-24
Added
- ordered
- yaml.load
- yaml.loads
- constructed
- extractor
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
Built Distribution
Hashes for sonotoria-0.3.8-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 1e478b16d0b094455569ef1072dcfab5ef7954cb5b90dfa72e01f746615bcf9f |
|
MD5 | 9990e32a032eaaf14113f9712e37fa57 |
|
BLAKE2b-256 | c62a9f9cd933b03d303407d5bf5d2b51e3d1bb28704fdc2fd91e25bb925abb2e |