Compare commits

6 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
11 changed files with 386 additions and 30 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.4.0"
version = "0.4.3"
dependencies = [
"hashlink",
"minijinja",

View File

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

View File

@@ -1,5 +1,14 @@
#!/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

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,6 +4,9 @@ use minijinja::Environment;
mod render;
use render::{Renderer, IndexItem, build_jinja_env, Template};
mod version;
use version::VERSION;
const SRC_PATH: &'static str = "./src/";
const OUT_PATH: &'static str = "./html/";
@@ -60,7 +63,12 @@ fn render_index(
};
let dest_path: &Path = &cur_path.join(format!("{}.{}", friendly, extention));
// render the content
println!("INFO: render {}", dest_path.to_str().unwrap());
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(content) => {
let _ = fs::write(dest_path, content);
@@ -70,9 +78,16 @@ fn render_index(
}
else {
// file is an asset, no rendering done for assets
let dest_path: &Path = &cur_path.join(friendly);
println!("INFO: copy {}", dest_path.to_str().unwrap());
let _ = fs::copy(src, dest_path);
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 => {
@@ -85,6 +100,10 @@ fn render_index(
}
}
fn version() {
println!("version: {}", VERSION);
}
fn usage() {
println!("webtemplate [--output=<dir>] [--src=<dir>]");
}
@@ -136,6 +155,10 @@ fn main() {
"help" => {
usage();
}
"version" => {
version();
return;
}
_ => {
println!("ERROR: invalid option {}", option);
usage();

View File

@@ -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)
},