prosberry/posodobi_blog.sh

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"