make template generation more sophisticated

This commit is contained in:
ledocool 2025-09-28 11:01:39 +07:00
parent 197303c17b
commit 51fde22d0f
12 changed files with 257 additions and 132 deletions

View file

@ -7,42 +7,46 @@ Fediverse Fanzine
For template engine [bash-tpl](https://github.com/TekWizely/bash-tpl) is used. Bash-tpl template engine allows for bash injections into templates. I hope that most of options required are displayed in the example, since I have no idea what kind of design is coveted for fedizine.
Templating is split into 3 stages.
0. Template and files preparation
1. Template script generation
0. Template and structure preparation
1. Data population
2. Template population
### Template and files preparation
As an example a file [fedizine_template_example.html](fedizine_template_example.html) is provided. For now there's nothing fancy, it is just a modified index.html page.
### 0. Template and structure preparation
Curently there are two monthly templates: [fedizine_monthly_template.html](fedizine_monthly_template.html) and [fedizine_monthly_template.md](fedizine_monthly_template.md). Those desribe a montly edition of fedizine.
The template expects a folder named "contestants" in the same directory as itself. Contestants folder would hold a bunch of other directories, one per contestant. Names of those folders are not used in templating, but imagine you'd want something readable.
First action to be done is to call `generate_templates.sh`.
Every contestant folder should contain a `bio.txt` file. File's full name would be `contestants\%some_folder%\bio.txt`.
Such file should have following lines in following order:
1. Contestant name
2. Contestant bio written in a single line (no line breaks allowed); sorry it is scuffed for the first version
3. A line describing an artwork
4. A line describing an artwork
5. A line describint an artwork
6. ....
An amount of artworks isn't actually limited to just two.
`A line describing an artwork` would be broken up by `"` delimiter. Which means it sould look somewhat like this: `"ref1.webp" "Short description" "Alt text"`
1. First entry is file name. **Note that the file not listed in bio.txt will not be displayed in the final html**
2. Second entry is short visible description. It will be written next to the file.
3. Third entry is the image alt text.
### Template script generation
Once template file is sufficiently prepared, you can create a generation script with this command:
```
./bash-tpl fedizie_template.html > fedizine_generate.sh && chmod +x fedizine_generate.sh
generate_templates.sh april 6
```
This script doesn't require `bash-tpl` or template file and can be transferred elsewhere at will.
`generate_templates.sh` expects two arguments: folder name and amount of contestants.
After calling the script folder `april` will be created with proper folder structure inside. There would be two template scripts and a `template_data` folder.
**Note that running generate_templates.sh on an already created folder structure whould not destroy edits in generated files**
### 1. Data population
After folder structure is created, head to `template_data` and edit `title.txt`. It contains overall data for this months edition of fedizine.
Next step is to descend into `contestants` folder. It contains folders named `contestant_1...n`. Each describes one of the fedizine authors. Note that you can rename those folders however you like.
Descend into `contestant_...` folder. It would contain a `bio.txt` which holds contestant name and small one liner description. Then it also contains two folders: `wholesome` and `lewd`. Wholesome folder should contain **SFW** works while lewd is designated for **NSFW**.
Do not hesitate to leave folders open or delete them. I left checks in place.
### Template population
Once folder structure and data are prepared and template script is generated, put template script in the same directory where `contestants` folder would be and execute command:
Once all data put in it's respective places, run `generate_files.sh`.
```
./fedizine_generate.sh > generated.html
generate_files.sh april
```
This will create `generated.html` file which should be served to the end user.
This will parse `april` folder and create 4 files in `april`:
- fedizine.html
- fedizine.md
- fedizine-html.pdf
- fedizine-md.pdf
fedizine.html - contains html template presumable for a web server
fedizine.md - contains markdown, used mainly for pdf generation
fedizine-html.pdf - a pdf file generated from fedizine.html
fedizine-md.pdf - a pdf file generated from fedizine.md
**Note! Pandoc does not crunch .webp format. If any of the images are .webp, pdf generation WILL fail.**

View file

@ -1,4 +0,0 @@
Contestant name
Contestant bio written in a signle string without any line breaks.
ref1.webp"Short description" "Alt text"
ref2.webp"Short description 2" "Alt text 2"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 976 KiB

View file

@ -1,4 +0,0 @@
Contestant name
Contestant bio written in a signle string without any line breaks.
ref3.webp "Short description" "Alt text"
ref4.webp "Short description 2" "Alt text 2"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 627 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 326 KiB

View file

@ -0,0 +1,98 @@
<!doctype html>
<html lang="en">
%
TITLE_PATH="./template_data/title.txt"
readarray -t FEDIZINE_TITLE < ${TITLE_PATH}
%
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title><% ${FEDIZINE_TITLE[0]} %></title>
<style>
body { font-family: sans-serif; margin: 2em auto; max-width: 700px; line-height: 1.6; background: #fafafa; color: #222; }
h1 { font-size: 2.5em; margin-bottom: 0.2em; color: #6b46c1; }
h2 { margin-top: 1.5em; color: #444; border-bottom: 2px solid #ddd; padding-bottom: 0.3em; }
p, li { font-size: 1em; }
ul { margin-top: 0.5em; }
a { color: #6b46c1; text-decoration: none; }
a:hover { text-decoration: underline; }
div.highlight { background: #fef3c7; padding: 0.2em 0.4em; border-radius: 4px; }
div.blur { filter: blur(5px); -webkit-filter: blur(5px); -moz-filter: blur(5px); -o-filter: blur(5px); -ms-filter: blur(5px);}
</style>
</head>
<body>
<h1><% ${FEDIZINE_TITLE[1]} %></h1>
<p><% ${FEDIZINE_TITLE[2]} %></p>
<h2>This month submissions</h2>
%
CONTESTANT_DIR="./template_data/contestants"
CONTESTANT_DIRECTORY="./template_data/contestants/*"
if [ "$(ls -A $CONTESTANT_DIR)" ]; then
for CONTESTANT in $CONTESTANT_DIRECTORY
do
%
<div class="contestant-box">
%
CONTESTANT_BIO="${CONTESTANT}/bio.txt"
readarray -t CONTESTANT_DATA < ${CONTESTANT_BIO}
%
<div class="contestant-entry">
<h3><% ${CONTESTANT_DATA[0]} %><h3>
<small><% ${CONTESTANT_DATA[1]} %></small>
<div class="contestant-images">
%
CONTESTANT_WHOLESOME_DIR="${CONTESTANT}/wholesome"
CONTESTANT_WHOLESOME_PATH="${CONTESTANT}/wholesome/*"
if [ -d "$CONTESTANT_WHOLESOME_DIR" ]; then
if [ "$(ls -A $CONTESTANT_WHOLESOME_DIR)" ]; then
for WHOLESOME_IMAGE in $CONTESTANT_WHOLESOME_PATH
do
%
<div class="contestant-image">
<img src="<% $WHOLESOME_IMAGE %>" width="300" />
</div>
%
done
fi
fi
%
</div>
<div class="contestant-images">
%
CONTESTANT_LEWD_DIR="${CONTESTANT}/lewd"
CONTESTANT_LEWD_PATH="${CONTESTANT}/lewd/*"
if [ -d "$CONTESTANT_LEWD_DIR" ]; then
if [ "$(ls -A $CONTESTANT_LEWD_DIR)" ]; then
for LEWD_IMAGE in $CONTESTANT_LEWD_PATH
do
%
<div class="contestant-image blur lewd" onclick="lewdify(this)">
<img src="<% $LEWD_IMAGE %>" width="300" />
</div>
%
done;
fi
fi
%
</div>
</div>
</div>
%
done;
fi
%
<h2>Contact</h2>
<p>Email: <a href="mailto:waifuism@tutanota.com">waifuism@tutanota.com</a><br>
Misskey: <a href="https://mai.waifuism.life/@waifu">@waifu@mai.waifuism.life</a></p>
<script>
function lewdify(source)
{
console.log("lewded!")
source.classList.toggle("blur");
}
</script>
</body>
</html>

View file

@ -0,0 +1,55 @@
%
TITLE_PATH="./template_data/title.txt"
readarray -t FEDIZINE_TITLE < ${TITLE_PATH}
%
# <% ${FEDIZINE_TITLE[1]} %>
<% ${FEDIZINE_TITLE[2]} %>
## This month submissions
%
CONTESTANT_DIR="./template_data/contestants"
CONTESTANT_DIRECTORY="./template_data/contestants/*"
if [ "$(ls -A $CONTESTANT_DIR)" ]; then
for CONTESTANT in $CONTESTANT_DIRECTORY
do
CONTESTANT_BIO="${CONTESTANT}/bio.txt"
readarray -t CONTESTANT_DATA < ${CONTESTANT_BIO}
%
### <% ${CONTESTANT_DATA[0]} %>
<% ${CONTESTANT_DATA[1]} %>
%
CONTESTANT_WHOLESOME_DIR="${CONTESTANT}/wholesome"
CONTESTANT_WHOLESOME_PATH="${CONTESTANT}/wholesome/*"
if [ -d "$CONTESTANT_WHOLESOME_DIR" ]; then
if [ "$(ls -A $CONTESTANT_WHOLESOME_DIR)" ]; then
for WHOLESOME_IMAGE in $CONTESTANT_WHOLESOME_PATH
do
%
![wholesome](<% $WHOLESOME_IMAGE %>)
%
done;
fi
fi
CONTESTANT_LEWD_DIR="${CONTESTANT}/lewd"
CONTESTANT_LEWD_PATH="${CONTESTANT}/lewd/*"
if [ -d "$CONTESTANT_LEWD_DIR" ]; then
if [ "$(ls -A $CONTESTANT_LEWD_DIR)" ]; then
for LEWD_IMAGE in $CONTESTANT_LEWD_PATH
do
%
![lewd](<% $LEWD_IMAGE %>)
%
done;
fi
fi
done;
fi
%
# Contact
**Email:** waifuism@tutanota.com
**Misskey:** [@waifu@mai.waifuism.life](https://mai.waifuism.life/@waifu)

View file

@ -1,96 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Fedizine - A Fanzine on the Fediverse</title>
<style>
body { font-family: sans-serif; margin: 2em auto; max-width: 700px; line-height: 1.6; background: #fafafa; color: #222; }
h1 { font-size: 2.5em; margin-bottom: 0.2em; color: #6b46c1; }
h2 { margin-top: 1.5em; color: #444; border-bottom: 2px solid #ddd; padding-bottom: 0.3em; }
p, li { font-size: 1em; }
ul { margin-top: 0.5em; }
a { color: #6b46c1; text-decoration: none; }
a:hover { text-decoration: underline; }
.highlight { background: #fef3c7; padding: 0.2em 0.4em; border-radius: 4px; }
</style>
</head>
<body>
<h1>Fedizine</h1>
<p>A monthly multipage fanzine made on the fedi and for the fedi.</p>
<h2>How It Works</h2>
<ul>
<li>Two monthly A4 artworks per artist</li>
<li>Artwork 1: A set theme decided by poll or popular demand</li>
<li>Artwork 2: Free space, up to you</li>
<li>Any kind of art or photography is welcome</li>
<li><strong>No AI-generated images</strong></li>
<li>Released both as a catalogue (on this page) and as a downloadable document</li>
</ul>
<h2>Status</h2>
<p>If you're interested in participating, reach out before starting to draw, and share your ideas. Release date is TBD, but you'll have a few weeks to work. More updates will be posted soon.</p>
<h2>September Theme</h2>
<p><strong>A foxgirl milf Pleromatan</strong></p>
<h2>Attempt at making a template</h2>
%
CONTESTANT_DIRECTORY="./contestants/*"
for CONTESTANT in $CONTESTANT_DIRECTORY
do
%
<div class="contestant-box">
%
CONTESTANT_BIO="${CONTESTANT}/bio.txt"
readarray -t CONTESTANT_DATA < ${CONTESTANT_BIO}
%
<div>
<h3><% ${CONTESTANT_DATA[0]} %><h3>
<small><% ${CONTESTANT_DATA[1]} %></small>
%
CONTESTANT_DATA_LENGTH=${#CONTESTANT_DATA[@]}
for (( j=2; j<${CONTESTANT_DATA_LENGTH}; j++ ));
do
readarray -t IMAGE_LINES < <( sed -r 's/"+ *"?/\n/g' <<< ${CONTESTANT_DATA[$j]} | sed -r '/^\s*$/d' | sed -r '/^ +/d' )
IMAGE_PATH="$CONTESTANT/${IMAGE_LINES[0]}"
IMAGE_ALT="${IMAGE_LINES[2]}"
IMAGE_DESCRIPTION="${IMAGE_LINES[1]}"
%
<div class="contestant-image">
<img src="<% $IMAGE_PATH %>" alt="<% $IMAGE_ALT %>" width="300" />
<span class="image-title"><b><% $IMAGE_DESCRIPTION %></b></span>
</div>
%
done;
%
</div>
</div>
<img src="<% $image %>" alt="Reference 4" width="300">
%
done;
%
<h2>Guidelines</h2>
<ul>
<li>Nothing illegal in the USA or Argentina</li>
<li>No politics</li>
<li>No slurs</li>
<li>No overly violent or sexual content</li>
<li>Submissions must pass a basic quality standard (editors discretion)</li>
</ul>
<p>Attempts to get around these rules will be ignored.</p>
<h2>Specs</h2>
<p>Page size: A4 (210 × 297 mm)<br>
Resolution: 300 ppi<br>
2552 × 3578 px<br>
Preferred format: PNG</p>
<h2>Contact</h2>
<p>Email: <a href="mailto:waifuism@tutanota.com">waifuism@tutanota.com</a><br>
Misskey: <a href="https://mai.waifuism.life/@waifu">@waifu@mai.waifuism.life</a></p>
</body>
</html>

9
generate_files.sh Executable file
View file

@ -0,0 +1,9 @@
#!/bin/bash
FEDIZINE_DIR="$1"
cd $FEDIZINE_DIR
./fedizine_html.sh > "fedizine.html"
./fedizine_md.sh > "fedizine.md"
pandoc fedizine.md -o fedizine-md.pdf
pandoc fedizine.html -o fedizine-html.pdf

63
generate_templates.sh Executable file
View file

@ -0,0 +1,63 @@
#!/bin/bash
FEDIZINE_DIR="$1"
FEDIZINE_DATA_DIR="$FEDIZINE_DIR/template_data"
CONTESTANT_AMOUNT="$2"
function dump_title
{
DIR=$1
if [ -f "$DIR/title.txt" ]; then
echo "Title exists"
return;
fi
echo "Dumping $DIR/title.txt"
touch "$DIR/title.txt"
echo "Fedizine Title (html only)" >> "$DIR/title.txt"
echo "Fedizine Header" >> "$DIR/title.txt"
echo "Fedizine Prompt" >> "$DIR/title.txt"
}
function dump_bio
{
BIO_PATH=$1
i=$2
BIO_FILE="$BIO_PATH/bio.txt"
if [ -f $BIO_FILE ]; then
echo "$BIO_FILE exists"
return;
fi
echo "Dumping $BIO_FILE"
touch "$BIO_FILE"
echo "Contestant $i" >> "$BIO_FILE"
echo "Contestant bio in single string" >> "$BIO_FILE"
}
function create_templates
{
TEMPLATE_PATH=$1
HTML_TEMPLATE_FILE="fedizine_html.sh"
MD_TEMPLATE_FILE="fedizine_md.sh"
echo "Creating templates"
./bash-tpl fedizine_monthly_template.html > "$TEMPLATE_PATH/$HTML_TEMPLATE_FILE" && chmod +x "$TEMPLATE_PATH/$HTML_TEMPLATE_FILE"
./bash-tpl fedizine_monthly_template.md > "$TEMPLATE_PATH/$MD_TEMPLATE_FILE" && chmod +x "$TEMPLATE_PATH/$MD_TEMPLATE_FILE"
}
echo "Creating $FEDIZINE_DATA_DIR"
mkdir $FEDIZINE_DATA_DIR -p
dump_title $FEDIZINE_DATA_DIR
for ((i=1;i<=$CONTESTANT_AMOUNT;++i)) do
mkdir "$FEDIZINE_DATA_DIR/contestants/contestant_$i/wholesome" -p
mkdir "$FEDIZINE_DATA_DIR/contestants/contestant_$i/lewd" -p
dump_bio "$FEDIZINE_DATA_DIR/contestants/contestant_$i" $i
done
create_templates $FEDIZINE_DIR