# `terender` - Render tera templates from data files `terender` is a simple command-line tool for rendering template files in [tera template format](https://tera.netlify.app/) simply using structured input data from a file. Currently supported file formats for the structured data are [JSON](https://json.org/), [TOML](https://toml.io/) and [YAML](https://yaml.org/). It does detect these only based on the file name extension, no inspection of the contents is done. For now, the file extension must be lowercase. Once [rust-lang #70516](https://github.com/rust-lang/rust/issues/70516) is in the stable compiler, I will use that to make the detection case-insensitive. If a file does contain data that can't be parsed, the tool will abort with an error message. If you're interested in adding a new format that is supported by [serde](https://docs.rs/serde/), please either [submit an issue](https://gitlab.com/silwol/terender/-/issues) or [create a merge request](https://gitlab.com/silwol/terender/-/merge_requests). For information on how to write `tera` templates, take a look at their [documentation](https://tera.netlify.app/docs/#templates). ## Usage A short usage example for transforming from a simple markdown template file with some json data into the rendered markdown. Contents of `products.template.md`: ```markdown # Our products {% for category in categories %} ## {{ category.name }} ({{ category.articles | length }} articles) {% for article in category.articles -%} * {{ article }} {% endfor -%} {% endfor -%} ``` Contents of `products.json`: ```json { "categories": [ { "name": "Sports", "articles": [ "Training shoes", "Bicycle" ] }, { "name": "Electronics", "articles": [ "Mobile phone", "USB memory stick", "E-Book reader" ] }, { "name": "Food", "articles": [ "Cheese", "Apple", "Milk" ] } ] } ``` Running `terender`: ``` $ terender products.template.md products.json # Our products ## Sports (2 articles) * Training shoes * Bicycle ## Electronics (3 articles) * Mobile phone * USB memory stick * E-Book reader ## Food (3 articles) * Cheese * Apple * Milk $ ``` ## Installation ### Prerequisites You need a working installation of the rust development environment, namely `rustc` and `cargo`. These can either be obtained from your operating system if it provides it (e.g. `apt install rustc` on Debian-based operating systems), or through . ### How to install The typical command for installation is: ``` cargo install terender ``` If you already have a version of the tool installed and want to overwrite it, you need to add the `-f` parameter: ``` cargo install -f terender ``` ## Special cases ### Top-level non-object in a file single data file The `tera` template rendering is only capable of rendering entities that represent objects with named fields (e.g. JSON object, or YAML mmappings). If a data input file contains something else at top-level, such as an array / list / sequence, or a primitive type, that entity gets wrapped into an object containing a single field named `data` in order to allow processing of that input. ```json [ "hello", "world" ] ``` would be changed to ```json { "data": [ "hello", "world" ] } ``` before processing. ### Using multiple data files In case you would like to use multiple data files in a rendering, you can do so. If you pass multiple data file parameters, these will be wrapped into a top-level object containing a `data` field which is an array enclosing all the data files. If passing these two files to the process: ```toml # This is file1.toml [details] version = "1.0" ``` ```json { "information": "this is file2.json" } ``` the data passed to the template would look like this (in JSON): ```json { "data": [ { "details": { "version": "1.0" } }, { "information": "this is file2.json" } ] } ``` ## Technical details This tool is just a very small implementation plumbing what already exists. The heavy lifting is done in library crates used by this tool: * [tera](https://docs.rs/tera) * [serde](https://docs.rs/serde), [serde_json](https://docs.rs/serde_json), [serde_yaml](https://docs.rs/serde_yaml), [toml](https://docs.rs/toml) * [structopt](https://docs.rs/structopt), [clap](https://docs.rs/clap) * [anyhow](https://docs.rs/anyhow) It is all because of these excellent implementations that this crate can be short and easily implemented. ## A note to package maintainers If you'd like to package this tool for an operating system distribution, feel free to do so. I'd be happy if you inform me when doing so, but it's not mandatory. If you would like to deploy shell completion scripts with your package, these can be generated by setting the `TERENDER_GENERATE_SHELL_COMPLETIONS` environment variable to a relative or absolute directory path where the completion files for all shells supported by [clap](https://docs.rs/clap/2.33.3/clap/enum.Shell.html) are generated. ## Changelog ### Version 0.1.3 * Allow using multiple data input files ### Version 0.1.2 * Add support for YAML data files * Add support for TOML data files ### Version 0.1.1 * Add support for processing toplevel non-object types by wrapping them into an object with a `data` field. ### Version 0.1.0 * Initial release