Skip to content

Commit

Permalink
Reworked template loading
Browse files Browse the repository at this point in the history
  • Loading branch information
TCA166 committed Jul 20, 2024
1 parent d6eff65 commit 7b37c59
Show file tree
Hide file tree
Showing 11 changed files with 107 additions and 44 deletions.
14 changes: 9 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
[package]
name = "ck3_history_extractor"
version = "0.2.3"
version = "0.2.4"
edition = "2021"
authors = ["TCA"]
description = "A tool for generating a encyclopedia from your CK3 save file"
documentation = "https://tca166.github.io/CK3-history-extractor/ck3_history_extractor/"
readme = "./README.md"
homepage = "https://tca166.github.io/CK3-history-extractor/TCA166's%20history/index.html"
repository = "https://github.com/TCA166/CK3-history-extractor"
license = "MIT"
keywords = ["Crusader Kings 3"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[target.x86_64-pc-windows-gnu]
linker = "/usr/bin/x86_64-w64-mingw32-gcc"
ar = "/usr/bin/x86_64-w64-mingw32-gcc-ar"

[dependencies]
minijinja = "2.0.1"
serde = {version="1.0.198" , features=["rc"] }
Expand Down
3 changes: 3 additions & 0 deletions config.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[target.x86_64-pc-windows-gnu]
linker = "/usr/bin/x86_64-w64-mingw32-gcc"
ar = "/usr/bin/x86_64-w64-mingw32-gcc-ar"
3 changes: 2 additions & 1 deletion src/display/timeline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::{game_object::GameId, structures::DerivedRef};
use super::super::{
game_object::GameString,
game_state::GameState,
jinja_env::TIMELINE_TEMPLATE_NAME,
structures::{Character, Culture, Faith, GameObjectDerived, Title},
types::{Shared, Wrapper, WrapperMut},
};
Expand Down Expand Up @@ -319,7 +320,7 @@ impl Renderable for Timeline {
}

fn get_template() -> &'static str {
"timelineTemplate.html"
TIMELINE_TEMPLATE_NAME
}

fn render_all(&self, stack: &mut Vec<RenderableType>, renderer: &mut Renderer) {
Expand Down
90 changes: 58 additions & 32 deletions src/jinja_env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,46 @@ static INT_TITLE_TEMPLATE: &str = include_str!("../templates/titleTemplate.html"
#[cfg(internal)]
static INT_TIMELINE_TEMPLATE: &str = include_str!("../templates/timelineTemplate.html");

pub const H_TEMPLATE_NAME: &str = "homeTemplate";
pub const C_TEMPLATE_NAME: &str = "charTemplate";
pub const CUL_TEMPLATE_NAME: &str = "cultureTemplate";
pub const DYN_TEMPLATE_NAME: &str = "dynastyTemplate";
pub const FAITH_TEMPLATE_NAME: &str = "faithTemplate";
pub const TITLE_TEMPLATE_NAME: &str = "titleTemplate";
pub const TIMELINE_TEMPLATE_NAME: &str = "timelineTemplate";
const TEMPLATE_NAMES: [&str; 7] = [
H_TEMPLATE_NAME,
C_TEMPLATE_NAME,
CUL_TEMPLATE_NAME,
DYN_TEMPLATE_NAME,
FAITH_TEMPLATE_NAME,
TITLE_TEMPLATE_NAME,
TIMELINE_TEMPLATE_NAME,
];

/// # Environment creation
///
/// Create a new [Environment] with the filters and templates needed for the project.
/// If the internal flag is set to true, it will use the internal templates, otherwise it will use the templates in the templates folder.
/// If the templates folder does not exist, it will attempt use the internal templates regardless of the setting.
///
/// **This function leaks memory.**
///
/// ## Env specifics
///
/// The environment will have no html escaping.
///
/// ### Filters
///
/// The environment will have the following filters:
/// - [render_ref] - renders a reference to another object
/// - [handle_tooltips] - removes tooltips from the text
///
/// ### Globals
///
/// The environment will have the following globals:
/// - map_present - whether the map is present
/// - no_vis - whether the visualizations are disabled
pub fn create_env(internal: bool, map_present: bool, no_vis: bool) -> Environment<'static> {
let mut env = Environment::new();
env.add_filter("render_ref", render_ref);
Expand All @@ -32,49 +67,40 @@ pub fn create_env(internal: bool, map_present: bool, no_vis: bool) -> Environmen
if internal || !Path::new("./templates").exists() {
#[cfg(internal)]
{
env.add_template("homeTemplate.html", INT_H_TEMPLATE)
.unwrap();
env.add_template("charTemplate.html", INT_C_TEMPLATE)
.unwrap();
env.add_template("cultureTemplate.html", INT_CUL_TEMPLATE)
env.add_template(H_TEMPLATE_NAME, INT_H_TEMPLATE).unwrap();
env.add_template(C_TEMPLATE_NAME, INT_C_TEMPLATE).unwrap();
env.add_template(CUL_TEMPLATE_NAME, INT_CUL_TEMPLATE)
.unwrap();
env.add_template("dynastyTemplate.html", INT_DYN_TEMPLATE)
env.add_template(DYN_TEMPLATE_NAME, INT_DYN_TEMPLATE)
.unwrap();
env.add_template("faithTemplate.html", INT_FAITH_TEMPLATE)
env.add_template(FAITH_TEMPLATE_NAME, INT_FAITH_TEMPLATE)
.unwrap();
env.add_template("titleTemplate.html", INT_TITLE_TEMPLATE)
env.add_template(TITLE_TEMPLATE_NAME, INT_TITLE_TEMPLATE)
.unwrap();
env.add_template("timelineTemplate.html", INT_TIMELINE_TEMPLATE)
env.add_template(TIMELINE_TEMPLATE_NAME, INT_TIMELINE_TEMPLATE)
.unwrap();
}
#[cfg(not(internal))]
{
panic!("Internal templates requested but not compiled in");
}
} else {
// LEAKS MEMORY
let h_template = Box::new(fs::read_to_string("templates/homeTemplate.html").unwrap());
env.add_template("homeTemplate.html", h_template.leak())
.unwrap();
let c_template = Box::new(fs::read_to_string("templates/charTemplate.html").unwrap());
env.add_template("charTemplate.html", c_template.leak())
.unwrap();
let cul_template = Box::new(fs::read_to_string("templates/cultureTemplate.html").unwrap());
env.add_template("cultureTemplate.html", cul_template.leak())
.unwrap();
let dyn_template = Box::new(fs::read_to_string("templates/dynastyTemplate.html").unwrap());
env.add_template("dynastyTemplate.html", dyn_template.leak())
.unwrap();
let faith_template = Box::new(fs::read_to_string("templates/faithTemplate.html").unwrap());
env.add_template("faithTemplate.html", faith_template.leak())
.unwrap();
let title_template = Box::new(fs::read_to_string("templates/titleTemplate.html").unwrap());
env.add_template("titleTemplate.html", title_template.leak())
.unwrap();
let timeline_template =
Box::new(fs::read_to_string("templates/timelineTemplate.html").unwrap());
env.add_template("timelineTemplate.html", timeline_template.leak())
.unwrap();
let template_dir = fs::read_dir("templates").unwrap();
for entry in template_dir {
let entry = entry.unwrap();
let file_name = entry.file_name();
//get the name of the file without the extension
let name = file_name.to_str().unwrap().splitn(2, '.').next().unwrap();
//it needs to be a template file
let i = TEMPLATE_NAMES.iter().position(|&x| x == name);
if i.is_none() {
continue;
}
// WARNING! LEAKS MEMORY
let template = Box::new(fs::read_to_string(entry.path()).unwrap());
env.add_template(TEMPLATE_NAMES[i.unwrap()], template.leak())
.unwrap();
}
}
env
}
Expand Down
3 changes: 2 additions & 1 deletion src/structures/character.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::{
display::{Cullable, Localizer, Renderable, RenderableType, Renderer, TreeNode},
game_object::{GameObject, GameString, SaveFileValue},
game_state::GameState,
jinja_env::C_TEMPLATE_NAME,
types::{Wrapper, WrapperMut},
};

Expand Down Expand Up @@ -829,7 +830,7 @@ impl Renderable for Character {
}

fn get_template() -> &'static str {
"charTemplate.html"
C_TEMPLATE_NAME
}

fn get_subdir() -> &'static str {
Expand Down
3 changes: 2 additions & 1 deletion src/structures/culture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use super::super::{
display::{Cullable, Localizer, Renderable, RenderableType, Renderer, TreeNode},
game_object::{GameObject, GameString},
game_state::GameState,
jinja_env::CUL_TEMPLATE_NAME,
};

use super::{serialize_array, DummyInit, GameId, GameObjectDerived, Shared};
Expand Down Expand Up @@ -168,7 +169,7 @@ impl Renderable for Culture {
}

fn get_template() -> &'static str {
"cultureTemplate.html"
CUL_TEMPLATE_NAME
}

fn get_subdir() -> &'static str {
Expand Down
3 changes: 2 additions & 1 deletion src/structures/dynasty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use super::super::{
display::{Cullable, Localizer, Renderable, RenderableType, Renderer},
game_object::{GameObject, GameString, SaveFileValue},
game_state::GameState,
jinja_env::DYN_TEMPLATE_NAME,
types::{Wrapper, WrapperMut},
};
use super::{
Expand Down Expand Up @@ -304,7 +305,7 @@ impl Renderable for Dynasty {
}

fn get_template() -> &'static str {
"dynastyTemplate.html"
DYN_TEMPLATE_NAME
}

fn get_subdir() -> &'static str {
Expand Down
3 changes: 2 additions & 1 deletion src/structures/faith.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use super::super::{
display::{Cullable, Localizer, Renderable, RenderableType, Renderer},
game_object::{GameObject, GameString},
game_state::GameState,
jinja_env::FAITH_TEMPLATE_NAME,
types::{Wrapper, WrapperMut},
};
use super::{Character, DerivedRef, DummyInit, GameId, GameObjectDerived, Shared};
Expand Down Expand Up @@ -128,7 +129,7 @@ impl Renderable for Faith {
}

fn get_template() -> &'static str {
"faithTemplate.html"
FAITH_TEMPLATE_NAME
}

fn get_subdir() -> &'static str {
Expand Down
3 changes: 2 additions & 1 deletion src/structures/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ use super::super::{
display::{Cullable, Localizer, Renderable, RenderableType, Renderer},
game_object::{GameObject, GameString},
game_state::GameState,
jinja_env::H_TEMPLATE_NAME,
types::Wrapper,
};

Expand Down Expand Up @@ -85,7 +86,7 @@ impl Renderable for Player {
}

fn get_template() -> &'static str {
"homeTemplate.html"
H_TEMPLATE_NAME
}

fn render_all(&self, stack: &mut Vec<RenderableType>, renderer: &mut Renderer) {
Expand Down
3 changes: 2 additions & 1 deletion src/structures/title.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use super::super::{
display::{Cullable, Localizer, Renderable, RenderableType, Renderer},
game_object::{GameObject, GameString, SaveFileValue},
game_state::GameState,
jinja_env::TITLE_TEMPLATE_NAME,
types::{Wrapper, WrapperMut},
};
use super::{serialize_array, Character, DerivedRef, DummyInit, GameId, GameObjectDerived, Shared};
Expand Down Expand Up @@ -341,7 +342,7 @@ impl Renderable for Title {
}

fn get_template() -> &'static str {
"titleTemplate.html"
TITLE_TEMPLATE_NAME
}

fn get_subdir() -> &'static str {
Expand Down
23 changes: 23 additions & 0 deletions templates/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Templates

This directory contains the templates that are used by the tool.
These are included in the executables you find in releases so unless you are tinkering with your own templates you need not even look here.
However if you are looking to tinker with the templates keep reading.

## Internal templates

As mentioned previously these templates can be compiled in statically into the executable.
Wasteful? perhaps but greatly reduces the hassle of setting up the tool and allows for older versions to remain functional after updates to this directory.
By default they are not compiled in and you need to set the ```internal``` flag on compilation like this ```RUSTFLAGS="--cfg internal"``` to be able to use them.
You can force the use of the internal templates via the ```--internal``` flag on runtime, and they will be used by default if the ```templates``` directory is not in the cwd.

## External templates

If the ```templates``` directory is present then the tool will attempt to load the templates located there.
It's looking for files with the following names ```homeTemplate```, ```cultureTemplate```, ```dynastyTemplate```, ```faithTemplate```, ```homeTemplate```, ```timelineTemplate```, ```titleTemplate``` ignoring extensions so you can theoretically provide, for example, Markdown templates and have the utility create Markdown files.

## Custom templates

Creation of custom templates is something I greatly encourage.
I would love to see template packs or other similar things.
Just be sure you use the same Jinja variables as I do and your templates should work fine.

0 comments on commit 7b37c59

Please sign in to comment.