331 lines
10 KiB
Bash
Executable File
331 lines
10 KiB
Bash
Executable File
#!/bin/bash
|
|
set -euo pipefail
|
|
|
|
# --- Configuration ---
|
|
ARTICLES_DIR="blog/clanki"
|
|
BLOG_TEMPLATE="blog/template.html"
|
|
BLOG_INDEX="blog/index.html"
|
|
ARTICLE_TEMPLATE="blog/article-template.html"
|
|
HEADER_TEMPLATE_FILE="header-template.html"
|
|
FOOTER_TEMPLATE_FILE="footer-template.html"
|
|
|
|
PLACEHOLDER_TITLES=(
|
|
"Pripravljamo nove vsebine"
|
|
"Kratek vodič po delavnicah"
|
|
"Naslednji koraki"
|
|
)
|
|
PLACEHOLDER_DATES=(
|
|
"pomlad 2026"
|
|
"pomlad 2026"
|
|
"poletje 2026"
|
|
)
|
|
PLACEHOLDER_SUMMARIES=(
|
|
"Razmišljanja o tem, kako navdušiti učence za medkulturne pogovore in skupinske projekte."
|
|
"Kako strukturirati delavnico, ki vključuje starše, učitelje in otroke v enakopravnem dialogu."
|
|
"Sledi blogu za nove prispevke in praktične nasvete."
|
|
)
|
|
|
|
PLACEHOLDER_IMAGE="/assets/images/blog/placeholder.webp"
|
|
|
|
check_jq_dependency() {
|
|
if ! command -v jq &> /dev/null; then
|
|
echo "Error: 'jq' is not installed. Please install it to run this script." >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
find_article_files() {
|
|
find "$ARTICLES_DIR" -maxdepth 1 -type f -name "*.html" | sort -r
|
|
}
|
|
|
|
extract_metadata() {
|
|
local file="$1"
|
|
local metadata_json
|
|
metadata_json=$(perl -ne 'BEGIN{undef $/;} if (/<!--\s*(\{.*?})\s*-->/s) { print $1; exit }' "$file")
|
|
|
|
if [ -z "${metadata_json:-}" ]; then
|
|
echo ""
|
|
return
|
|
fi
|
|
|
|
if ! echo "$metadata_json" | jq -e . &> /dev/null; then
|
|
echo "Warning: Malformed JSON metadata in $file. Skipping article." >&2
|
|
echo ""
|
|
return
|
|
fi
|
|
|
|
echo "$metadata_json"
|
|
}
|
|
|
|
format_short_date() {
|
|
local iso_date="$1"
|
|
if [[ "$iso_date" =~ ^([0-9]{4})-([0-9]{2})-([0-9]{2})$ ]]; then
|
|
printf "%s.%s.%s" "${BASH_REMATCH[3]}" "${BASH_REMATCH[2]}" "${BASH_REMATCH[1]}"
|
|
else
|
|
echo "$iso_date"
|
|
fi
|
|
}
|
|
|
|
format_long_date() {
|
|
local iso_date="$1"
|
|
if [[ "$iso_date" =~ ^([0-9]{4})-([0-9]{2})-([0-9]{2})$ ]]; then
|
|
local year="${BASH_REMATCH[1]}"
|
|
local month="${BASH_REMATCH[2]}"
|
|
local day="${BASH_REMATCH[3]}"
|
|
local month_name
|
|
case "$month" in
|
|
01) month_name="januar" ;;
|
|
02) month_name="februar" ;;
|
|
03) month_name="marec" ;;
|
|
04) month_name="april" ;;
|
|
05) month_name="maj" ;;
|
|
06) month_name="junij" ;;
|
|
07) month_name="julij" ;;
|
|
08) month_name="avgust" ;;
|
|
09) month_name="september" ;;
|
|
10) month_name="oktober" ;;
|
|
11) month_name="november" ;;
|
|
12) month_name="december" ;;
|
|
*) month_name="$month" ;;
|
|
esac
|
|
printf "%s. %s %s" "$day" "$month_name" "$year"
|
|
else
|
|
echo "$iso_date"
|
|
fi
|
|
}
|
|
|
|
generate_featured_article_html() {
|
|
local file="$1"
|
|
local metadata_json="$2"
|
|
local title date image summary article_path long_date
|
|
|
|
title=$(echo "$metadata_json" | jq -r '.title')
|
|
date=$(echo "$metadata_json" | jq -r '.date')
|
|
image=$(echo "$metadata_json" | jq -r '.image')
|
|
summary=$(echo "$metadata_json" | jq -r '.summary // ""')
|
|
article_path=$(basename "$file")
|
|
long_date=$(format_long_date "$date")
|
|
|
|
cat <<EOF
|
|
<article class="featured-article" data-aos="fade-up">
|
|
<a href="/blog/clanki/${article_path}">
|
|
<img src="${image}" alt="${title}">
|
|
<div class="featured-article-content">
|
|
<p class="article-date">${long_date}</p>
|
|
<h2>${title}</h2>
|
|
<p>${summary}</p>
|
|
</div>
|
|
</a>
|
|
</article>
|
|
EOF
|
|
}
|
|
|
|
generate_recent_article_card_html() {
|
|
local file="$1"
|
|
local metadata_json="$2"
|
|
local title date image summary short_date article_path
|
|
|
|
title=$(echo "$metadata_json" | jq -r '.title')
|
|
date=$(echo "$metadata_json" | jq -r '.date')
|
|
image=$(echo "$metadata_json" | jq -r '.image')
|
|
summary=$(echo "$metadata_json" | jq -r '.summary // ""')
|
|
article_path=$(basename "$file")
|
|
short_date=$(format_short_date "$date")
|
|
|
|
cat <<EOF
|
|
<article class="recent-card">
|
|
<a href="/blog/clanki/${article_path}">
|
|
<img src="${image}" alt="${title}">
|
|
<h3>${title}</h3>
|
|
<p class="article-date">${short_date}</p>
|
|
<p>${summary}</p>
|
|
</a>
|
|
</article>
|
|
EOF
|
|
}
|
|
|
|
generate_archive_list_item_html() {
|
|
local file="$1"
|
|
local metadata_json="$2"
|
|
local title date short_date article_path
|
|
|
|
title=$(echo "$metadata_json" | jq -r '.title')
|
|
date=$(echo "$metadata_json" | jq -r '.date')
|
|
article_path=$(basename "$file")
|
|
short_date=$(format_short_date "$date")
|
|
|
|
cat <<EOF
|
|
<li><a href="/blog/clanki/${article_path}">${title}</a> - ${short_date}</li>
|
|
EOF
|
|
}
|
|
|
|
generate_placeholder_card_html() {
|
|
local index="$1"
|
|
local slot=$((index % ${#PLACEHOLDER_TITLES[@]}))
|
|
local title="${PLACEHOLDER_TITLES[$slot]}"
|
|
local date="${PLACEHOLDER_DATES[$slot]}"
|
|
local summary="${PLACEHOLDER_SUMMARIES[$slot]}"
|
|
|
|
cat <<EOF
|
|
<article class="recent-card placeholder-card">
|
|
<a href="#">
|
|
<img src="${PLACEHOLDER_IMAGE}" alt="${title}">
|
|
<h3>${title}</h3>
|
|
<p class="article-date">${date}</p>
|
|
<p>${summary}</p>
|
|
</a>
|
|
</article>
|
|
EOF
|
|
}
|
|
|
|
check_template_file() {
|
|
local file="$1"
|
|
if [ ! -f "$file" ]; then
|
|
echo "Error: Template file '$file' does not exist." >&2
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
check_template_file "$BLOG_TEMPLATE"
|
|
check_template_file "$ARTICLE_TEMPLATE"
|
|
check_template_file "$HEADER_TEMPLATE_FILE"
|
|
check_template_file "$FOOTER_TEMPLATE_FILE"
|
|
|
|
check_jq_dependency
|
|
|
|
ALL_ARTICLE_FILES=$(find_article_files)
|
|
VALID_ARTICLE_ENTRIES=()
|
|
|
|
for file in $ALL_ARTICLE_FILES; do
|
|
filename=$(basename "$file")
|
|
if [[ "$filename" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}-.*\.html$ ]]; then
|
|
metadata=$(extract_metadata "$file")
|
|
if [ -z "${metadata:-}" ]; then
|
|
continue
|
|
fi
|
|
article_date=$(echo "$metadata" | jq -r '.date // empty')
|
|
if [ -z "$article_date" ]; then
|
|
echo "Warning: Missing date in $file. Skipping article." >&2
|
|
continue
|
|
fi
|
|
VALID_ARTICLE_ENTRIES+=("${article_date}|${file}")
|
|
else
|
|
echo "Warning: Invalid filename format for $file. Expected YYYY-MM-DD-*.html. Skipping article." >&2
|
|
fi
|
|
done
|
|
|
|
if [ "${#VALID_ARTICLE_ENTRIES[@]}" -eq 0 ]; then
|
|
echo "No valid article files found in $ARTICLES_DIR."
|
|
exit 0
|
|
fi
|
|
|
|
SORTED_ENTRIES=$(printf "%s\n" "${VALID_ARTICLE_ENTRIES[@]}" | LC_ALL=C sort -t'|' -k1,1r -k2,2)
|
|
|
|
FEATURED_ARTICLE_HTML=""
|
|
RECENT_ARTICLES_HTML=""
|
|
ARCHIVE_HTML=""
|
|
|
|
ARTICLE_COUNT=0
|
|
RECENT_COUNT=0
|
|
PLACEHOLDER_INDEX=0
|
|
|
|
while IFS='|' read -r _ file; do
|
|
metadata=$(extract_metadata "$file")
|
|
if [ -z "${metadata:-}" ]; then
|
|
continue
|
|
fi
|
|
|
|
if [ "$ARTICLE_COUNT" -eq 0 ]; then
|
|
FEATURED_ARTICLE_HTML=$(generate_featured_article_html "$file" "$metadata")
|
|
elif [ "$ARTICLE_COUNT" -le 3 ]; then
|
|
RECENT_ARTICLES_HTML+=$'\n'"$(generate_recent_article_card_html "$file" "$metadata")"
|
|
RECENT_COUNT=$((RECENT_COUNT + 1))
|
|
else
|
|
ARCHIVE_HTML+=$'\n'"$(generate_archive_list_item_html "$file" "$metadata")"
|
|
fi
|
|
|
|
ARTICLE_COUNT=$((ARTICLE_COUNT + 1))
|
|
done <<< "$SORTED_ENTRIES"
|
|
|
|
if [ "$RECENT_COUNT" -lt 3 ]; then
|
|
for ((i=RECENT_COUNT; i<3; i++)); do
|
|
RECENT_ARTICLES_HTML+=$'\n'"$(generate_placeholder_card_html "$PLACEHOLDER_INDEX")"
|
|
PLACEHOLDER_INDEX=$((PLACEHOLDER_INDEX + 1))
|
|
done
|
|
fi
|
|
|
|
if [ -z "${FEATURED_ARTICLE_HTML:-}" ]; then
|
|
echo "Warning: No featured article generated." >&2
|
|
fi
|
|
|
|
export FEATURED_ARTICLE_HTML
|
|
export RECENT_ARTICLES_HTML
|
|
export ARCHIVE_HTML
|
|
export BLOG_TEMPLATE
|
|
export BLOG_INDEX
|
|
export HEADER_TEMPLATE_FILE
|
|
export FOOTER_TEMPLATE_FILE
|
|
|
|
python3 <<'PY'
|
|
import os
|
|
from pathlib import Path
|
|
|
|
template = Path(os.environ["BLOG_TEMPLATE"]).read_text()
|
|
template = template.replace("__HEADER_CONTENT__", Path(os.environ["HEADER_TEMPLATE_FILE"]).read_text())
|
|
template = template.replace("__NAJNOVEJSI_CLANEK__", os.environ.get("FEATURED_ARTICLE_HTML", ""))
|
|
template = template.replace("__CAKAJOCI_CLANKI__", os.environ.get("RECENT_ARTICLES_HTML", ""))
|
|
template = template.replace("__ARHIV_SEZNAM__", os.environ.get("ARCHIVE_HTML", ""))
|
|
template = template.replace("__FOOTER_CONTENT__", Path(os.environ["FOOTER_TEMPLATE_FILE"]).read_text())
|
|
Path(os.environ["BLOG_INDEX"]).write_text(template)
|
|
PY
|
|
|
|
echo "Blog page generated successfully at $BLOG_INDEX"
|
|
|
|
# Generate individual article pages
|
|
echo "Generating individual article pages..."
|
|
|
|
ARTICLE_COUNT=0
|
|
while IFS='|' read -r _ file; do
|
|
metadata=$(extract_metadata "$file")
|
|
if [ -z "${metadata:-}" ]; then
|
|
continue
|
|
fi
|
|
|
|
title=$(echo "$metadata" | jq -r '.title')
|
|
date=$(echo "$metadata" | jq -r '.date')
|
|
image=$(echo "$metadata" | jq -r '.image')
|
|
summary=$(echo "$metadata" | jq -r '.summary // ""')
|
|
long_date=$(format_long_date "$date")
|
|
|
|
# Extract article content (everything after the JSON comment)
|
|
content=$(perl -0777 -ne 'if (/--\u003e\s*(.*)$/s) { print $1 }' "$file")
|
|
|
|
# Export variables for Python
|
|
export ARTICLE_TITLE="$title"
|
|
export ARTICLE_DATE="$long_date"
|
|
export ARTICLE_IMAGE="$image"
|
|
export ARTICLE_SUMMARY="$summary"
|
|
export ARTICLE_CONTENT="$content"
|
|
export ARTICLE_FILE="$file"
|
|
|
|
python3 \u003c\u003c'PY'
|
|
import os
|
|
from pathlib import Path
|
|
|
|
template = Path(os.environ["ARTICLE_TEMPLATE"]).read_text()
|
|
template = template.replace("__HEADER_CONTENT__", Path(os.environ["HEADER_TEMPLATE_FILE"]).read_text())
|
|
template = template.replace("__ARTICLE_TITLE__", os.environ.get("ARTICLE_TITLE", ""))
|
|
template = template.replace("__ARTICLE_DATE__", os.environ.get("ARTICLE_DATE", ""))
|
|
template = template.replace("__ARTICLE_IMAGE__", os.environ.get("ARTICLE_IMAGE", ""))
|
|
template = template.replace("__ARTICLE_SUMMARY__", os.environ.get("ARTICLE_SUMMARY", ""))
|
|
template = template.replace("__ARTICLE_CONTENT__", os.environ.get("ARTICLE_CONTENT", ""))
|
|
template = template.replace("__FOOTER_CONTENT__", Path(os.environ["FOOTER_TEMPLATE_FILE"]).read_text())
|
|
Path(os.environ["ARTICLE_FILE"]).write_text(template)
|
|
PY
|
|
|
|
ARTICLE_COUNT=$((ARTICLE_COUNT + 1))
|
|
echo " Generated: $(basename "$file")"
|
|
done \u003c\u003c\u003c "$SORTED_ENTRIES"
|
|
|
|
echo "Generated $ARTICLE_COUNT article pages successfully"
|