Skip to content

Commit

Permalink
feat: add support for include and inherit (#9)
Browse files Browse the repository at this point in the history
* Flag to parse everything in the same path as the template
* Logic for 'include' flag
* Option to define a different 'include' path
* Logic for `include-path` option
* Document new `--include` flag and `--include-path` option
* Update **tera cli** usage documentation
* Tera's **include** example
* Tera's **inheritance** example
* Update markdown README file
  • Loading branch information
tandiljuan authored Sep 7, 2021
1 parent 55be2a2 commit 592f365
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 14 deletions.
25 changes: 19 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ By default, your ENV variables will be loaded at the root of the context data. F

While the syntax is a little more verbose, paired with `--fail-on-collision`, this option allows ensuring that nothing happens in your back.

### External files

Using the `--include` flag, the command will scan recursively for files that could be [included](https://tera.netlify.app/docs/#include), used as [macros](https://tera.netlify.app/docs/#macros) or for [inheritance](https://tera.netlify.app/docs/#inheritance). By default, it will scan the folder where the main template is located, unless the `--include-path` option is given.

From this repository, you can test **include** feature with the command `USER="[YOURNAME]" tera --template data/include/hello.txt --include --env-only` and test **inheritance** feature with `USER="[YOURNAME]" tera --template data/inheritance/child.txt --inherit --env-only`.

### Output

By default,
Expand Down Expand Up @@ -159,13 +165,20 @@ Passing the `-a | --escape` flag allows escaping the content.
be raised
--fail-on-collision if you prefer your data to override the ENV
-h, --help Prints help information
-i, --include This flag tells the command to parse all templates found in the same
path where the given template is located [aliases: inherit]
-s, --stdin The context data can be passed using stdin
-V, --version Prints version information

OPTIONS:
--env-key <env-key> By default, if --env is set, the environment variables will be
attached at the root of the context. This is convenient but may end
up conflicting with your data. To prevent collisions, you can
provide a custom key with this option
-o, --out <out> Optional output file. If not passed, using stdout
-t, --template <template> Location of the template
--env-key <env-key>
By default, if --env is set, the environment variables will be attached at the root of
the context. This is convenient but may end up conflicting with your data. To prevent
collisions, you can provide a custom key with this option

--include-path <include-path>
Option to define a different path from which search and parse templates [aliases:
inherit-path]

-o, --out <out> Optional output file. If not passed, using stdout
-t, --template <template> Location of the template
6 changes: 6 additions & 0 deletions README_src.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,12 @@ By default, your ENV variables will be loaded at the root of the context data. F

While the syntax is a little more verbose, paired with `--fail-on-collision`, this option allows ensuring that nothing happens in your back.

=== External files

Using the `--include` flag, the command will scan recursively for files that could be https://tera.netlify.app/docs/#include[included], used as https://tera.netlify.app/docs/#macros[macros] or for https://tera.netlify.app/docs/#inheritance[inheritance]. By default, it will scan the folder where the main template is located, unless the `--include-path` option is given.

From this repository, you can test *include* feature with the command `USER="[YOURNAME]" tera --template data/include/hello.txt --include --env-only` and test *inheritance* feature with `USER="[YOURNAME]" tera --template data/inheritance/child.txt --inherit --env-only`.

=== Output

By default,
Expand Down
2 changes: 2 additions & 0 deletions data/include/hello.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Hello {{ USER }}, this is the Hello template.
{% include "world.txt" %}
1 change: 1 addition & 0 deletions data/include/world.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This is the world template.
7 changes: 7 additions & 0 deletions data/inheritance/base.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
This is a BASE template.

The default greetings shows "Greetings!" but we can improve that with inheritance!

{% block greetings %}
Greetings!
{% endblock greetings %}
7 changes: 7 additions & 0 deletions data/inheritance/child.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{% extends "base.txt" %}

The following block will replace our greetings in the base.

{% block greetings %}
May the force be with you **{{ USER }}**
{% endblock greetings %}
19 changes: 13 additions & 6 deletions doc/usage.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,20 @@ FLAGS:
be raised
--fail-on-collision if you prefer your data to override the ENV
-h, --help Prints help information
-i, --include This flag tells the command to parse all templates found in the same
path where the given template is located [aliases: inherit]
-s, --stdin The context data can be passed using stdin
-V, --version Prints version information

OPTIONS:
--env-key <env-key> By default, if --env is set, the environment variables will be
attached at the root of the context. This is convenient but may end
up conflicting with your data. To prevent collisions, you can
provide a custom key with this option
-o, --out <out> Optional output file. If not passed, using stdout
-t, --template <template> Location of the template
--env-key <env-key>
By default, if --env is set, the environment variables will be attached at the root of
the context. This is convenient but may end up conflicting with your data. To prevent
collisions, you can provide a custom key with this option

--include-path <include-path>
Option to define a different path from which search and parse templates [aliases:
inherit-path]

-o, --out <out> Optional output file. If not passed, using stdout
-t, --template <template> Location of the template
37 changes: 35 additions & 2 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use clap::{crate_name, crate_version, Clap};
use env_logger::Env;
use log::{debug, info, trace};
use opts::*;
use std::{fs::File, io::Write};
use std::{fs::canonicalize, fs::File, io::Write, string::String};
use tera::{Context, Tera};

fn main() -> Result<(), String> {
Expand All @@ -22,14 +22,47 @@ fn main() -> Result<(), String> {

let autoescape = opts.autoescape;
let output = opts.out.to_owned();
let mut include = opts.include;
let mut path = canonicalize(&opts.template).unwrap();

if opts.include_path.is_some() {
include = true;
path = canonicalize(opts.include_path.as_ref().unwrap()).unwrap();
}

let mut wrapped_context = wrapped_context::WrappedContext::new(opts);
wrapped_context.create_context();

let context: &Context = wrapped_context.context();
trace!("context:\n{:#?}", context);

let rendered = Tera::one_off(&template, context, autoescape).unwrap();
let rendered;

if include {
let mut dir = path.to_str().unwrap();

if path.is_file() {
dir = path.parent().unwrap().to_str().unwrap();
}

let glob = dir.to_owned() + "/**/*";

let mut tera = match Tera::new(&glob) {
Ok(t) => t,
Err(e) => {
println!("Parsing error(s): {}", e);
::std::process::exit(1);
}
};

if !autoescape {
tera.autoescape_on(vec![]);
}

rendered = tera.render_str(&template, context).unwrap();
} else {
rendered = Tera::one_off(&template, context, autoescape).unwrap();
}

println!("{}", rendered);

Expand Down
9 changes: 9 additions & 0 deletions src/opts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ pub struct Opts {
#[clap(short, long)]
pub template: PathBuf,

/// This flag tells the command to parse all templates found in the same
/// path where the given template is located.
#[clap(short, long, visible_alias = "inherit")]
pub include: bool,

/// Option to define a different path from which search and parse templates.
#[clap(long, visible_alias = "inherit-path")]
pub include_path: Option<PathBuf>,

/// Location of the context data. This file can be of the following type:
/// json | toml | yaml. If you prefer to pass the data as stdin, use `--stdin`
#[clap(index = 1, required_unless_present_any = &["stdin", "env-only"], conflicts_with = "env-only")]
Expand Down

0 comments on commit 592f365

Please sign in to comment.