8 Commits

Author SHA1 Message Date
266850dccf update dependencys 2025-08-26 00:38:10 +02:00
db3fa1b75f bump version 2025-08-26 00:09:01 +02:00
e83a9f3f51 add --version flag 2025-08-26 00:07:59 +02:00
ad582caa5b add more error logging 2025-08-25 23:22:56 +02:00
f230d455f2 update runner lable 2025-08-25 21:14:52 +02:00
ae73f21f67 add conatiner for webserver 2025-08-25 21:00:35 +02:00
c47cf77dbd bump version and add build script 2025-08-23 12:46:38 +02:00
cc3e106145 update cli and follow template extentions 2025-08-23 12:38:59 +02:00
13 changed files with 542 additions and 61 deletions

View File

@@ -0,0 +1,55 @@
on:
push:
tags: "container-*"
env:
REGISTRY: git.gay
IMAGE_NAME: ${{ github.repository }}
# There is a single job in this workflow. It's configured to run on the latest
# available version of Ubuntu.
jobs:
build-and-push-image:
runs-on: elf
steps:
- name: Checkout repository
uses: https://code.forgejo.org/actions/checkout@v4
# Uses the `docker/login-action` action to log in to the Container
# registry registry using the account and password that will publish the
# packages. Once published, the packages are scoped to the account defined
# here.
- name: Log in to the Container registry
uses: https://code.forgejo.org/docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.REGISTRY_TOKEN }}
# This step uses [docker/metadata-action](https://code.forgejo.org/docker/metadata-action#about)
# to extract tags and labels that will be applied to the specified image.
# The `id` "meta" allows the output of this step to be referenced in a
# subsequent step. The `images` value provides the base name for the tags
# and labels.
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: https://code.forgejo.org/docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
latest
# This step uses the `docker/build-push-action` action to build the image,
# based on your repository's `Dockerfile`. If the build succeeds, it
# pushes the image to GitHub Packages.
# It uses the `context` parameter to define the build's context as the set
# of files located in the specified path. For more information, see
# "[Usage](https://code.forgejo.org/docker/build-push-action#usage)" in
# the README of the `docker/build-push-action` repository.
# It uses the `tags` and `labels` parameters to tag and label the image
# with the output from the "meta" step.
- name: Build and push Docker image
uses: https://code.forgejo.org/docker/build-push-action@v6
with:
# the path to the container files (the `Dockerfile`)
context: docker
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}

4
.gitignore vendored
View File

@@ -1,2 +1,4 @@
/target
/html
/html
/src/version.rs
/webTemplate-*

42
Cargo.lock generated
View File

@@ -19,15 +19,15 @@ checksum = "7d902e3d592a523def97af8f317b08ce16b7ab854c1985a0c671e6f15cebc236"
[[package]]
name = "bitflags"
version = "2.9.1"
version = "2.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
checksum = "34efbcccd345379ca2868b2b2c9d3782e9cc58ba87bc7d79d5b53d9c9ae6f25d"
[[package]]
name = "cfg-if"
version = "1.0.1"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
[[package]]
name = "encoding_rs"
@@ -55,9 +55,9 @@ dependencies = [
[[package]]
name = "hashbrown"
version = "0.15.4"
version = "0.15.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5"
checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
dependencies = [
"foldhash",
]
@@ -91,9 +91,9 @@ checksum = "38d1115007560874e373613744c6fba374c17688327a71c1476d1a5954cc857b"
[[package]]
name = "minijinja"
version = "2.11.0"
version = "2.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e60ac08614cc09062820e51d5d94c2fce16b94ea4e5003bb81b99a95f84e876"
checksum = "a9f264d75233323f4b7d2f03aefe8a990690cdebfbfe26ea86bcbaec5e9ac990"
dependencies = [
"memo-map",
"self_cell",
@@ -103,9 +103,9 @@ dependencies = [
[[package]]
name = "proc-macro2"
version = "1.0.95"
version = "1.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
dependencies = [
"unicode-ident",
]
@@ -141,9 +141,9 @@ dependencies = [
[[package]]
name = "regex"
version = "1.11.1"
version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
checksum = "23d7fd106d8c02486a8d64e778353d1cffe08ce79ac2e82f540c86d0facf6912"
dependencies = [
"aho-corasick",
"memchr",
@@ -153,9 +153,9 @@ dependencies = [
[[package]]
name = "regex-automata"
version = "0.4.9"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6"
dependencies = [
"aho-corasick",
"memchr",
@@ -164,9 +164,9 @@ dependencies = [
[[package]]
name = "regex-syntax"
version = "0.8.5"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001"
[[package]]
name = "ryu"
@@ -202,9 +202,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.141"
version = "1.0.143"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3"
checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a"
dependencies = [
"itoa",
"memchr",
@@ -214,9 +214,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.104"
version = "2.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
dependencies = [
"proc-macro2",
"quote",
@@ -243,7 +243,7 @@ checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c"
[[package]]
name = "webTemplate"
version = "0.3.0"
version = "0.4.3"
dependencies = [
"hashlink",
"minijinja",

View File

@@ -1,6 +1,6 @@
[package]
name = "webTemplate"
version = "0.3.0"
version = "0.4.3"
edition = "2024"
[dependencies]

16
build.sh Executable file
View File

@@ -0,0 +1,16 @@
#!/bin/sh
rm webTemplate-*
set -e
version="$(cat Cargo.toml | grep '^version' | sed -e 's/^.*"\([^"]*\)".*$/\1/')"
commit="$(git show --oneline -s | sed -e 's/ .*$//')"
dirty="$(test "$(git diff --shortstat 2> /dev/null | tail -n1)" == "" || echo -n "_drity" )"
echo "pub const VERSION: &'static str = \"${version} (${commit}${dirty})\";" >src/version.rs
cross build --target aarch64-unknown-linux-gnu --release
cargo build --release
cp target/aarch64-unknown-linux-gnu/release/webTemplate webTemplate-aarch64
cp target/release/webTemplate webTemplate-x86_64

6
docker/000-default.conf Normal file
View File

@@ -0,0 +1,6 @@
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/public
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

19
docker/Dockerfile Normal file
View File

@@ -0,0 +1,19 @@
FROM php:apache
RUN mkdir -p /var/www
WORKDIR /var/www
COPY 000-default.conf /etc/apache2/sites-available/000-default.conf
COPY apache2.conf /etc/apache2/apache2.conf
RUN apt-get update && apt-get install -y curl && \
a2enmod rewrite
COPY build.sh /var/www/build.sh
RUN curl https://gitea.finnvanreenen.nl/LailaTheElf/webTemplate/releases/download/v0.4.0/webTemplate-x86_64 \
--output /var/www/webtemplate && \
chmod +x /var/www/webtemplate && \
chmod +x /var/www/build.sh
VOLUME /var/www/src
CMD ["/var/www/build.sh"]

225
docker/apache2.conf Normal file
View File

@@ -0,0 +1,225 @@
# This is the main Apache server configuration file. It contains the
# configuration directives that give the server its instructions.
# See http://httpd.apache.org/docs/2.4/ for detailed information about
# the directives and /usr/share/doc/apache2/README.Debian about Debian specific
# hints.
#
#
# Summary of how the Apache 2 configuration works in Debian:
# The Apache 2 web server configuration in Debian is quite different to
# upstream's suggested way to configure the web server. This is because Debian's
# default Apache2 installation attempts to make adding and removing modules,
# virtual hosts, and extra configuration directives as flexible as possible, in
# order to make automating the changes and administering the server as easy as
# possible.
# It is split into several files forming the configuration hierarchy outlined
# below, all located in the /etc/apache2/ directory:
#
# /etc/apache2/
# |-- apache2.conf
# | `-- ports.conf
# |-- mods-enabled
# | |-- *.load
# | `-- *.conf
# |-- conf-enabled
# | `-- *.conf
# `-- sites-enabled
# `-- *.conf
#
#
# * apache2.conf is the main configuration file (this file). It puts the pieces
# together by including all remaining configuration files when starting up the
# web server.
#
# * ports.conf is always included from the main configuration file. It is
# supposed to determine listening ports for incoming connections which can be
# customized anytime.
#
# * Configuration files in the mods-enabled/, conf-enabled/ and sites-enabled/
# directories contain particular configuration snippets which manage modules,
# global configuration fragments, or virtual host configurations,
# respectively.
#
# They are activated by symlinking available configuration files from their
# respective *-available/ counterparts. These should be managed by using our
# helpers a2enmod/a2dismod, a2ensite/a2dissite and a2enconf/a2disconf. See
# their respective man pages for detailed information.
#
# * The binary is called apache2. Due to the use of environment variables, in
# the default configuration, apache2 needs to be started/stopped with
# /etc/init.d/apache2 or apache2ctl. Calling /usr/bin/apache2 directly will not
# work with the default configuration.
# Global configuration
#
#
# ServerRoot: The top of the directory tree under which the server's
# configuration, error, and log files are kept.
#
# NOTE! If you intend to place this on an NFS (or otherwise network)
# mounted filesystem then please read the Mutex documentation (available
# at <URL:http://httpd.apache.org/docs/2.4/mod/core.html#mutex>);
# you will save yourself a lot of trouble.
#
# Do NOT add a slash at the end of the directory path.
#
#ServerRoot "/etc/apache2"
#
# The accept serialization lock file MUST BE STORED ON A LOCAL DISK.
#
#Mutex file:${APACHE_LOCK_DIR} default
#
# The directory where shm and other runtime files will be stored.
#
DefaultRuntimeDir ${APACHE_RUN_DIR}
#
# PidFile: The file in which the server should record its process
# identification number when it starts.
# This needs to be set in /etc/apache2/envvars
#
PidFile ${APACHE_PID_FILE}
#
# Timeout: The number of seconds before receives and sends time out.
#
Timeout 300
#
# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to "Off" to deactivate.
#
KeepAlive On
#
# MaxKeepAliveRequests: The maximum number of requests to allow
# during a persistent connection. Set to 0 to allow an unlimited amount.
# We recommend you leave this number high, for maximum performance.
#
MaxKeepAliveRequests 100
#
# KeepAliveTimeout: Number of seconds to wait for the next request from the
# same client on the same connection.
#
KeepAliveTimeout 5
# These need to be set in /etc/apache2/envvars
User ${APACHE_RUN_USER}
Group ${APACHE_RUN_GROUP}
#
# HostnameLookups: Log the names of clients or just their IP addresses
# e.g., www.apache.org (on) or 204.62.129.132 (off).
# The default is off because it'd be overall better for the net if people
# had to knowingly turn this feature on, since enabling it means that
# each client request will result in AT LEAST one lookup request to the
# nameserver.
#
HostnameLookups Off
# ErrorLog: The location of the error log file.
# If you do not specify an ErrorLog directive within a <VirtualHost>
# container, error messages relating to that virtual host will be
# logged here. If you *do* define an error logfile for a <VirtualHost>
# container, that host's errors will be logged there and not here.
#
ErrorLog ${APACHE_LOG_DIR}/error.log
#
# LogLevel: Control the severity of messages logged to the error_log.
# Available values: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the log level for particular modules, e.g.
# "LogLevel info ssl:warn"
#
LogLevel warn
# Include module configuration:
IncludeOptional mods-enabled/*.load
IncludeOptional mods-enabled/*.conf
# Include list of ports to listen on
Include ports.conf
# Sets the default security model of the Apache2 HTTPD server. It does
# not allow access to the root filesystem outside of /usr/share and /var/www.
# The former is used by web applications packaged in Debian,
# the latter may be used for local directories served by the web server. If
# your system is serving content from a sub-directory in /srv you must allow
# access here, or in any related virtual host.
<Directory />
Options FollowSymLinks
AllowOverride None
Require all denied
</Directory>
<Directory /usr/share>
AllowOverride None
Require all granted
</Directory>
<Directory /var/www/>
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
</Directory>
#<Directory /srv/>
# Options Indexes FollowSymLinks
# AllowOverride None
# Require all granted
#</Directory>
# AccessFileName: The name of the file to look for in each directory
# for additional configuration directives. See also the AllowOverride
# directive.
#
AccessFileName .htaccess
#
# The following lines prevent .htaccess and .htpasswd files from being
# viewed by Web clients.
#
<FilesMatch "^\.ht">
Require all denied
</FilesMatch>
#
# The following directives define some format nicknames for use with
# a CustomLog directive.
#
# These deviate from the Common Log Format definitions in that they use %O
# (the actual bytes sent including headers) instead of %b (the size of the
# requested file), because the latter makes it impossible to detect partial
# requests.
#
# Note that the use of %{X-Forwarded-For}i instead of %h is not recommended.
# Use mod_remoteip instead.
#
LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent
# Include of directories ignores editors' and dpkg's backup files,
# see README.Debian for details.
# Include generic snippets of statements
IncludeOptional conf-enabled/*.conf
# Include the virtual host configurations:
IncludeOptional sites-enabled/*.conf

5
docker/build.sh Normal file
View File

@@ -0,0 +1,5 @@
#!/bin/sh
/var/www/webtemplate --output=/var/www/public --src=/var/www/src
apache2-foreground

View File

@@ -4,36 +4,90 @@ use minijinja::Environment;
mod render;
use render::{Renderer, IndexItem, build_jinja_env, Template};
const SRC_PATH: &'static str = "../src";
mod version;
use version::VERSION;
const SRC_PATH: &'static str = "./src/";
const OUT_PATH: &'static str = "./html/";
fn render_index(out_path: &Path, index: &IndexItem, cur_path: &Path, site_index: &Renderer, jinja_env: Option<&Environment>) {
fn render_index(
out_path: &Path,
index: &IndexItem,
cur_path: &Path,
site_index: &Renderer,
templates: Option<Vec<Box<Template>>>,
jinja_env: Option<&Environment>
) {
let dest_path: &Path = &cur_path.join(&index.friendly);
println!("dest_path: {:?}", dest_path);
// println!("dest_path: {:?}", dest_path);
let templates = match templates {
Some(template) => template,
None => Template::index(&site_index.path.join("templates")),
};
let jinja_env = match jinja_env {
Some(env) => env,
None => &build_jinja_env(Template::index(&site_index.path.join("templates"))),
None => &build_jinja_env(templates.clone()),
};
match &index.src {
Some(src) => {
// a source file is available. try to render it
let friendly = match index.friendly.len() {
0 => String::from("index"),
_ => index.friendly.clone()
};
if !index.is_asset {
let dest_path: &Path = &cur_path.join(format!("{}.{}", friendly, index.target_extention));
// find template
let templ: Option<Template> = {
let mut out = None;
for templ in templates.clone() {
if let Some(templ) = templ.search(index.template.clone()) {
out = Some(templ);
break;
}
}
out
};
// get output file extention
let extention = match index.target_extention.len() {
0 => match templ {
Some(templ) => templ.extention,
None => String::from("html")
}
_ => index.target_extention.clone()
};
let dest_path: &Path = &cur_path.join(format!("{}.{}", friendly, extention));
// render the content
let dest_path_str = dest_path.to_str();
if dest_path_str == None {
println!("ERROR: dest path is None for page: {}", friendly);
return;
}
println!("INFO: render {}", dest_path_str.unwrap());
match site_index.render_page(index, &site_index.site, jinja_env) {
Some(html) => {
let _ = fs::write(dest_path, html);
Some(content) => {
let _ = fs::write(dest_path, content);
},
None => todo!(),
};
}
else {
let _ = fs::copy(src, &cur_path.join(friendly));
// file is an asset, no rendering done for assets
let dest_path: &Path = &cur_path.join(friendly.clone());
match dest_path.to_str() {
Some(dest_path_str) => {
println!("INFO: copy {}", dest_path_str);
let _ = fs::copy(src, dest_path);
}
None => {
println!("ERROR: dest path is None for asset: {}", friendly);
}
}
}
},
None => {
@@ -42,40 +96,91 @@ fn render_index(out_path: &Path, index: &IndexItem, cur_path: &Path, site_index:
};
for page in &index.sub_pages {
render_index(out_path, page, dest_path, &site_index, Some(&jinja_env));
render_index(out_path, page, dest_path, &site_index, Some(templates.clone()), Some(&jinja_env));
}
}
fn version() {
println!("version: {}", VERSION);
}
fn usage() {
println!("webtemplate [--output=<dir>] [--src=<dir>]");
}
fn main() {
let mut src_path_str: String = SRC_PATH.to_string();
let mut out_path_str: String = OUT_PATH.to_string();
let mut i: u8 = 0;
for arg in env::args() {
match i {
0 => {}
1 => {
src_path_str = arg;
if arg.starts_with("--") {
let mut parts = arg.split('=');
let option: String = match parts.next() {
None => {
println!("WARN: argument parsing: faild to split argument");
continue;
},
Some(str) => {
let mut str = String::from(str);
str.remove(0);
str.remove(0);
str
}
};
let value = match parts.next() {
None => None,
Some(str) => Some(String::from(str))
};
match option.as_str() {
"output" => {
if let Some(value) = value {
out_path_str = value;
} else {
println!("ERROR: no value given for output");
usage();
return;
}
}
"src" => {
if let Some(value) = value {
src_path_str = value;
} else {
println!("ERROR: no value given for output");
usage();
return;
}
}
"help" => {
usage();
}
"version" => {
version();
return;
}
_ => {
println!("ERROR: invalid option {}", option);
usage();
return;
}
}
2 => {
out_path_str = arg;
}
_ => {}
}
i += 1;
}
let src_path = Path::new(&src_path_str);
let out_path = Path::new(&out_path_str);
let index = Renderer::index(src_path).unwrap();
println!("");
println!("index:");
println!("{:?}", index);
// scan all pages, template, components, etc.
let index = match Renderer::index(src_path) {
Some(index) => index,
None => {
println!("ERROR: src directory not found ({})", src_path_str);
return;
},
};
// render website
let _ = fs::create_dir_all(out_path);
render_index(out_path, &index.site, out_path, &index, None);
render_index(out_path, &index.site, out_path, &index, None, None);
}

View File

@@ -27,7 +27,7 @@ fn build_jinja_env_dir<'a>(templates: Vec<Box<indexer::Template>>) -> Environmen
if let Some(src) = plate.src {
let name = format!("{}/{}", template.name.clone(), plate.name.clone());
match env.add_template_owned(name.clone(), src) {
Ok(_) => println!("template name: {name}"),
Ok(_) => {}, //println!("template name: {name}"),
Err(err) => println!("ERROR: failt to add template \"{name}\" ({err:?})"),
}
}
@@ -98,14 +98,26 @@ impl Renderer {
let split = indexer::split_params(content);
match parse_md(split.md, jinja_env) {
Some(md) => {
let template = jinja_env.get_template(&page.template).unwrap();
let html = template.render(context! {
let template = match jinja_env.get_template(&page.template) {
Ok(templ) => templ,
Err(_) => {
println!("ERROR: jinja: failed to get template");
return None;
},
};
let html = match template.render(context! {
index => index.to_minijinja(),
is_error_not_found => false,
url => page.get_url(),
body => md,
params => Renderer::convert_yaml(split.yaml)
}).unwrap();
}) {
Ok(out) => out,
Err(_) => {
println!("ERROR: jinja: failed to render template");
return None;
},
};
Some(html)
},

View File

@@ -7,14 +7,23 @@ pub mod indexer {
#[derive(Debug)]
pub struct IndexItem {
// path to source file. If none, it is a directory without an index page
pub src: Option<String>,
// if it is an asset file
pub is_asset: bool,
// url path with starting slash
pub path: String,
// the title of the page
pub title: String,
// url friendly name
pub friendly: String,
// if the page sould be in the site navigator
pub public: bool,
// name of the remplate to use
pub template: String,
// list of sub pages
pub sub_pages: Vec<Box<IndexItem>>,
// extention of the output file
pub target_extention: String,
}
impl IndexItem {
@@ -28,7 +37,7 @@ pub mod indexer {
public: false,
sub_pages: Vec::new(),
template: String::from("default"),
target_extention: String::from("html"),
target_extention: String::from(""),
}
}
@@ -199,7 +208,7 @@ pub mod indexer {
}
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct Template {
pub name: String,
pub extention: String,
@@ -218,14 +227,41 @@ pub mod indexer {
}
}
pub fn index(path: &Path) -> Vec<Box<Template>> {
match Template::scan_template(path) {
pub fn search(&self, path: String) -> Option<Self> {
let mut parts = path.split("/");
match parts.next() {
None => None,
Some(first) => {
if self.name == first {
let sub_path = parts.collect::<Vec<&str>>().join("/");
if sub_path.len() == 0 {
return Some(self.clone())
}
return self.search_sub(path)
}
None
}
}
}
fn search_sub(&self, path: String) -> Option<Self> {
for templ in self.sub_templates.clone() {
if let Some(templ) = templ.search(path.clone()) {
return Some(templ)
}
}
None
}
pub fn index(path: &Path) -> Vec<Box<Self>> {
match Self::scan_template(path) {
Some(templates) => templates.sub_templates,
None => Vec::new(),
}
}
fn scan_template(path: &Path) -> Option<Template> {
fn scan_template(path: &Path) -> Option<Self> {
let mut item = Template::new();
if let Some(file_name) = path.file_name() {
if let Some(file_name) = file_name.to_str() {
@@ -254,7 +290,7 @@ pub mod indexer {
let mut matches = re.captures_iter(&file_name);
if let Some(dot) = matches.next() {
let dot = dot.get(0).unwrap();
item.extention = file_name.clone().drain(dot.start()..).collect();
item.extention = file_name.clone().drain(dot.end()..).collect();
item.name = file_name.clone().drain(..dot.start()).collect();
return Some(item);
}

View File

@@ -110,7 +110,7 @@ fn md_preprocessor(md: &String, jinja_env: &Environment) -> String {
}
fn render_component(component: &str, args: Value, jinja_env: &Environment) -> Option<String> {
println!(" tag found: {component} <- {args}");
// println!(" tag found: {component} <- {args}");
match jinja_env.get_template(&format!("components/{component}")) {
Ok(ding) => {
// match ding.render(context! { args => args }) {