#!/usr/bin/zsh
#
# Quick Site Generator 2 is a static website generator inspired by Nikola.
# It is written for the Z shell (zsh) because that's what I use and also because I like it better than Bash.
#
# This script is an almost complete rewrite of my old script because it became overly complicated and
# had way too many bugs, even though it worked on simple sites.
#
# https://github.com/kekePower/qsgen2/
#
VERSION="0.4.0 beta 1" # Wed-2024-02-14
QSGEN="Quick Site Generator 2"
# Set to true or false
# This will show debug information from every function in this script
# You can also set debug=true in a single function if you want to debug only that specific one.
globaldebug=false
# Use Zsh fpath to set the path to some extra functions
fpath=(${HOME}/bin/include/common ${HOME}/bin/include/qsgen2/lang $fpath)
# In this case, let's load the 'include' function
autoload include
# Including some colors to the script
include common/colors
echo "${magenta}${blue_bg} ${QSGEN} ${end}${bold_white}${blue_bg}${VERSION} ${end}"
# Loading Zsh modules
zmodload zsh/files
zmodload zsh/datetime
# Check for, an source, the config file for this specific website
if [[ -f $(pwd)/config ]]; then
if (${globaldebug}); then echo "${red}Config file found and sourced${end}\n${yellow} - $(pwd)/config${end}"; fi
builtin source $(pwd)/config
else
echo "${red}Cannot find configuration file.${end}"
echo "${yellow} - Please create the file 'config' in your project directory.${end}"
exit
fi
# Load language
found=false
typeset -A qsgenlang
for dir in $fpath; do
if [[ -f "${dir}/${language}" ]]; then
# echo "Language file: ${dir}/${language}"
source "${dir}/${language}"
found=true
break
fi
done
if ! $found; then
echo "Language file '${language}' not found in fpath."
# Fallback or error handling
fi
#echo "Language loaded: ${language}"
#echo "Localization array contents: ${(@kv)qsgenlang}"
if (${globaldebug}); then
qsconfig=$( cat $(pwd)/config | grep -v \# | awk '{print substr($0, index($0, " ") + 1)}' )
echo "Content of Config file"
for qslines in ${qsconfig}
do
echo "${yellow}${qslines}${end}"
done
fi
function _msg() {
local type=$1
shift # Remove the first argument so $@ now contains only keys or additional strings
local full_msg=""
for arg in "$@"; do
if [[ -n "${qsgenlang[$arg]}" ]]; then
full_msg+="${qsgenlang[$arg]}"
else
full_msg+="$arg"
fi
done
# Determine the color based on the type
local color="${end}" # Default to no color if type is unrecognized
case $type in
std) color="${green}" ;;
info) color="${yellow}" ;;
debug) color="${red}" ;;
other) color="${bold_yellow}" ;;
sub) color="${magenta}" ;;
main) color="${white}${green_bg}" ;;
esac
# Use printf with %b to allow backslash escape interpretation
printf "${color}%b${end}\n" "${full_msg}"
}
function _version() {
_msg info "_qsgen2_msg_7" "-$(strftime "%Y")"
echo "${yellow}- https://github.com/kekePower/qsgen2/${end}"
_msg info "_qsgen2_msg_8" " '${1} help' " "_qsgen2_msg_8.1"
exit
}
function _help() {
# This will also be translated some time in the future
echo "This is where I'll write the Help documentation."
exit
}
if [[ "$1" == "version" || "$1" == "-v" || "$1" == "--version" ]]; then
_version ${0:t}
elif [[ "$1" == "help" || "$1" == "-h" || "$1" == "--help" ]]; then
_help ${0:t}
fi
# Define cache files for blogs and pages
blog_cache_file="${project_dir}/.blog_cache"
pages_cache_file="${project_dir}/.pages_cache"
case ${1} in
force)
_msg sub "_qsgen2_msg_2"
: >| "$blog_cache_file" # Truncate the blog cache before doing update
: >| "$pages_cache_file" # Truncate the page cache before doing update
;;
*)
# Nothing
;;
esac
# Let's check if qsgen2 can generate this site by checking if 'generator' is available
if [[ ! ${generator} ]] || [[ -d $(pwd)/.git ]]; then
_msg debug "_qsgen2_msg_3"
exit
fi
# We define the variable 'engine' based on what's in the 'config' file.
if [[ ${generator} == "native" ]]; then
# Usage: ${engine} ${1} - Where 1 is the file you want to convert
engine=_zhtml
export file_ext="qst"
elif [[ ${generator} == "markdown" ]]; then
if [[ ! -f /usr/local/bin/pandoc ]]; then
_msg other "_qsgen2_msg_4"
_msg other "https://github.com/jgm/pandoc/releases"
exit
else
# Usage: ${engine} ${1} - Where 1 is the file you want parsed
engine="/usr/local/bin/pandoc"
engine_opts=
export file_ext="md"
fi
else
_msg debug "_qsgen2_msg_5"
exit
fi
if (${globaldebug}); then _msg debug "_qsgen2_msg_6"; fi
builtin cd ${project_dir}
# Let's put these here for now.
export today=$(strftime "%Y-%m-%d - %T")
export blogdate=$(strftime "%a-%Y-%b-%d")
# Let's create arrays of all the files we'll be working on
function _list_pages() {
local debug=${globaldebug:-false}
# Initialize or clear the array to ensure it's empty before adding files
pages_file_array=()
export no_pages_found=false
# Temporarily set null_glob for this function
setopt local_options null_glob
# Using an array to directly capture matching files
local -a pages_files=(*.${file_ext})
if (( ${#pages_files} == 0 )); then
if ${debug}; then _msg debug "${0:t}_msg_1" " ${file_ext}."; fi
export no_pages_found=true
return
else
for file in "${pages_files[@]}"; do
if ${debug}; then _msg debug "${0:t}_msg_2" " ${file}"; fi
pages_file_array+=("$file")
done
fi
}
function _list_blogs() {
local debug=${globaldebug:-false}
# Initialize or clear the blogs array to ensure it's empty before adding files
blogs_file_array=()
export no_blogs_found=false
# Temporarily set null_glob for this function
setopt local_options null_glob
# Directly capture matching blog files into an array
local -a blog_files=(blog/*.blog(On))
if (( ${#blog_files[@]} == 0 )); then
if ${debug}; then _msg debug "${0:t}_msg_1"; fi
export no_blogs_found=true
return
else
for file in "${blog_files[@]}"
do
if ${debug}; then _msg debug "${0:t}_msg_2" " $file"; fi
blogs_file_array+=("$file")
done
fi
}
# BLOG CACHE
function _blog_cache() {
local debug=${globaldebug:-false}
_list_blogs
# Create an associative array for the blog cache
typeset -A blog_cache
# Load the existing blog cache
if [[ -f $blog_cache_file ]]; then
while IFS=':' read -r name hash; do
blog_cache[$name]=$hash
if (${debug}) _msg debug "${0:t}_msg_1" " ${blog_cache[${name}]}"
done < "$blog_cache_file"
fi
# Initialize the array for storing blog files to process
make_blog_array=()
# Process blog files
for blog_file in ${blogs_file_array[@]}; do
# Compute the current blog file hash
current_hash=$(md5sum "$blog_file" | awk '{print $1}')
if (${debug}) _msg debug "${0:t}_msg_2" " ${blog_file}"
if (${debug}) _msg debug "${0:t}_msg_3" " ${current_hash}"
# Check if the blog file is new or has changed
if [[ ${blog_cache[$blog_file]} != "$current_hash" ]]; then
if (${debug}) _msg debug "${0:t}_msg_4" " ${blog_file}"
if (${debug}) _msg debug "${0:t}_msg_5" " ${current_hash}"
# Blog file is new or has changed; add it to the processing array
make_blog_array+=("$blog_file")
# Update the blog cache with the new hash
blog_cache[$blog_file]=$current_hash
fi
done
# Rebuild the blog cache file from scratch
: >| "$blog_cache_file" # Truncate the file before writing
for name in "${(@k)blog_cache}"; do
echo "$name:${blog_cache[$name]}" >> "$blog_cache_file"
done
}
# PAGES CACHE
# Returns the array pages_array()
function _pages_cache() {
local debug=${globaldebug:-false}
# Create an associative array for the pages cache
typeset -A pages_cache
_list_pages
# Load the existing pages cache
if [[ -f $pages_cache_file ]]; then
while IFS=':' read -r name hash; do
pages_cache[$name]=$hash
if (${debug}) _msg debug "${0:t}_msg_1" " ${pages_cache[${name}]}"
done < "$pages_cache_file"
fi
# Initialize the array for storing pages files to process
pages_array=()
# Process pages files
for file in ${pages_file_array[@]}; do
# Compute the current blog file hash
current_hash=$(md5sum "$file" | awk '{print $1}')
if (${debug}) _msg debug "${0:t}_msg_2" " ${pages_cache[$file]}"
if (${debug}) _msg debug "${0:t}_msg_3" " current_cache: ${current_hash}"
# Check if the pages file is new or has changed
if [[ ${pages_cache[$file]} != "$current_hash" ]]; then
if (${debug}) _msg debug "${0:t}_msg_4" " ${pages_cache[$file]}"
if (${debug}) _msg debug "${0:t}_msg_5" " current_cache: ${current_hash}"
# Pages file is new or has changed; add it to the processing array
pages_array+=("$file")
# Update the pages cache with the new hash
pages_cache[$file]=$current_hash
fi
done
# Rebuild the pages cache file from scratch
: >| "$pages_cache_file" # Truncate the file before writing
for name in "${(@k)pages_cache}"; do
echo "$name:${pages_cache[$name]}" >> "$pages_cache_file"
done
}
function _last_updated() {
# This function updates #updated and #version tags in the provided string for buffers
local debug=${globaldebug:-false}
local upd_msg="Last updated ${today} by ${QSGEN} ${VERSION}"
if (${debug}); then _msg debug "${0:t}_msg_1"; fi
if (${debug}); then _msg debug "${0:t}_msg_2" " ${upd_msg}"; fi
local content="${1}"
# Perform the replacements
local updated_content=$(echo "${content}" | sed \
-e "s|#updated|${upd_msg}|")
# Return the updated content
echo "${updated_content}"
}
function _f_last_updated() {
# Updates #updated and #version tags in the provided file using Zsh
local debug=${globaldebug:-false}
# local file_path="${1}"
local upd_msg="Last updated ${today} by ${QSGEN} ${VERSION}"
if ${debug}; then
_msg debug "${0:t}_msg_1" " ${1}"
_msg debug "${0:t}_msg_2" " ${upd_msg}"
fi
# Read the file content into a variable
local content="$(<${1})"
# Perform the replacement
content="${content//#updated/${upd_msg}}"
if [[ -f "${1}" ]]; then
sed -i -e "s|#updated|${upd_msg}|" "${1}"
else
_msg debug "${0:t}_msg_3" " '${1}' " "${0:t}_msg_3.1"
fi
}
function _file_to_lower() {
local filename="${1}"
# Replace spaces with dashes
filename="${filename// /-}"
# Convert to lowercase and remove invalid characters
filename=$(echo "${filename}" | sed -e 's/^[^a-zA-Z0-9_.]+//g' -e 's/[^a-zA-Z0-9_-]+/-/g')
echo ${filename}
}
function _pages() {
# This function generates all the new and updated Pages
local debug=${globaldebug:-false}
# Load the cache for Pages
if (${debug}) _msg debug "${0:t}_msg_1"
_pages_cache
if [[ ${no_pages_found} == "true" ]]; then
_msg sub "${0:t}_msg_1"
return
fi
_msg main "${0:t}_msg_3"
if (( ${#pages_array[@]} > 0 )); then
# If pages_array is not empty, we do work
if (${debug}) _msg debug "${0:t}_msg_4"
for pages_in_array in ${pages_array[@]}
do
if (${debug}) _msg debug "${0:t}_msg_5"
local pages=${project_dir}/themes/${theme}/pages.tpl
# Let's check if we can access the pages.tpl file.
# It not, exit script.
if [[ ! -f ${pages} ]]; then
_msg info "${0:t}_msg_6" " ${pages}"
exit
else
# Read template once
if (${debug}) _msg debug "${0:t}_msg_7"
local pages_tpl="$(<${pages})"
fi
_msg std " - ${pages_in_array%.*}.html"
# Read the file once
if (${debug}) _msg debug "${0:t}_msg_9" " ${pages_in_array}"
local page_content="$(<${pages_in_array})"
# Grab the title from the Page
if (${debug}) _msg debug "${0:t}_msg_10"
if [[ ${generator} == "native" ]]; then
while read -r line
do
if [[ "$line" =~ ^#title=(.*) ]]; then
local page_title=${match[1]}
break
#local page_title=$( echo ${page_content} | head -2 | grep \#title | cut -d= -f2 )
fi
done <<< "$page_content"
elif [[ ${generator} == "markdown" ]]; then
while IFS= read -r line
do
# Check if the line starts with '#' and capture the line
if [[ "$line" == \#* ]]; then
# Remove all leading '#' characters and the first space (if present)
local page_title="${line#\#}" # Remove the first '#' character
page_title="${page_title#\#}" # Remove the second '#' character if present
page_title="${page_title#"${page_title%%[![:space:]]*}"}" # Trim leading whitespace
break # Exit the loop after finding the first heading
fi
done <<< ${page_content}
fi
if (${debug}) _msg debug "${0:t}_msg_11" " ${page_title}"
# Remove the #title line from the buffer. No longer needed.
if (${debug}) _msg debug "${0:t}_msg_12"
page_content=$( echo ${page_content} | grep -v \#title )
# HTML'ify the page content
if (${debug}) _msg debug "${0:t}_msg_13" " ${pages_in_array}"
if [[ ${generator} == "native" ]]; then
page_content=$( ${engine} "$page_content" )
# Look for links, images and videos and convert them if present.
if (${debug}) _msg debug "${0:t}_msg_14"
if [[ $( echo ${page_content} | grep \#link ) ]]; then
if (${debug}) _msg debug "${0:t}_msg_15"
page_content=$( _link "${page_content}" )
fi
if [[ $( echo ${page_content} | grep \#showimg ) ]]; then
if (${debug}) _msg debug "${0:t}_msg_16"
page_content=$( _image "${page_content}" )
fi
if [[ $( echo ${page_content} | grep \#ytvideo ) ]]; then
if (${debug}) _msg debug "${0:t}_msg_17"
page_content=$( _youtube "${page_content}" )
fi
elif [[ ${generator} == "markdown" ]]; then
page_content=$(echo "$page_content" | ${engine} ${engine_opts})
fi
# Replace every #pagetitle in pages_tpl
if (${debug}) _msg debug "${0:t}_msg_18"
pages_tpl=$(echo "${pages_tpl}" | perl -pe "s|#pagetitle|${page_title}|gs; s|#tagline|${site_tagline}|gs; s|#sitename|${site_name}|gs")
if (${debug}) _msg debug "${0:t}_msg_19"
# Use awk for multi-line and special character handling
pages_tpl=$( awk -v new_body="$page_content" '{sub(/BODY/, new_body)} 1' <(echo "${pages_tpl}") )
# Replace #updated with today's date and #version with Name and Version to footer
if (${debug}) _msg debug "${0:t}_msg_20"
pages_tpl=$( _last_updated ${pages_tpl} )
# Always use lowercase for file names
if (${debug}) _msg debug "${0:t}_msg_21"
pages_title_lower=$( _file_to_lower "${pages_in_array}" )
# Clean up unused tags, if any
if (${debug}) _msg debug "${0:t}_msg_22"
pages_tpl=$( _cleanup "${pages_tpl}" )
# Write pages_tpl to disk
# _msg std "Writing ${www_root}/${pages_title_lower%.*}.html to disk."
echo "${pages_tpl}" > ${www_root}/${pages_title_lower%.*}.html
# Insert the blog to the front page is blog_in_index is true and the file in the array is index.file_ext
# and if index.tmp.html exist and is not empty
if [[ ${pages_in_array} == "index.${file_ext}" && ${blog_in_index} == "true" && -s "${project_dir}/blog/index.tmp.html" ]]; then
if (${debug}) _msg sub "${0:t}_msg_23" " ${pages_in_array}"
if (${debug}) _msg sub "${0:t}_msg_24" " ${blog_in_index}"
if (${debug}) _msg sub "${0:t}_msg_25"
if (${debug}) ls -l ${project_dir}/blog/index.tmp.html
_add_blog_list_to_index
fi
done
export new_updated_pages=true
else
# Insert the blog to the front page is blog_in_index is true and the file in the array is index.file_ext
# and if index.tmp.html exist and is not empty
if [[ ${blog_in_index} == "true" && -s "${project_dir}/blog/index.tmp.html" ]]; then
_msg std "${0:t}_msg_26"
if (${debug}) _msg sub "${0:t}_msg_27" " ${pages_in_array}"
if (${debug}) _msg sub "${0:t}_msg_28" " ${blog_in_index}"
if (${debug}) _msg sub "${0:t}_msg_25"
if (${debug}) ls -l ${project_dir}/blog/index.tmp.html
_add_blog_list_to_index
fi
_msg sub "${0:t}_msg_29"
export new_updated_pages=false
fi
}
function _blogs() {
# This function either generates blog files or exports metadata based on the argument
local debug=${globaldebug:-false}
# Running function _list_blogs
if (${debug}) _msg debug "${0:t}_msg_1"
_list_blogs
if [[ ${no_blogs_found} == "true" ]]; then
_msg sub "${0:t}_msg_2"
return
fi
_msg main "${0:t}_msg_3"
# Running function _blog_cache
if (${debug}) _msg debug "${0:t}_msg_4"
_blog_cache
if (( ${#make_blog_array[@]} > 0 )); then
# Declare the array to hold metadata strings for each blog
BLOG_META_STR_ARRAY=()
# Regular blog creation process
if [[ -f ${project_dir}/themes/${theme}/blogs.tpl ]]; then
local blog_tpl=$(<"${project_dir}/themes/${theme}/blogs.tpl")
else
_msg info "${0:t}_msg_5"
exit
fi
for blog in "${make_blog_array[@]}"; do
if (${debug}) _msg debug "${0:t}_msg_6" " ${blog}"
local content="$(<"${blog}")"
local sdate btitle ingress body blog_index blog_dir blog_url
# Initialize variables to track if DATE and BLOG_TITLE are found
local date_found=false
local title_found=false
# Process content line by line
while IFS= read -r line
do
# Check for the DATE line
if [[ "${line}" == "DATE "* ]]; then
if (${debug}) _msg debug "${0:t}_msg_7"
date_found=true
fi
# Check for the BLOG_TITLE line
if [[ "${line}" == "BLOG_TITLE "* ]]; then
if (${debug}) _msg debug "${0:t}_msg_8"
title_found=true
fi
# If both DATE and BLOG_TITLE are found, no need to continue checking
if [[ "${date_found}" == true && "${title_found}" == true ]]; then
break
fi
done <<< "${content}"
# Check if DATE or BLOG_TITLE metadata is missing and log message
if [[ "${date_found}" == false ]]; then
_msg debug "${0:t}_msg_9" " ${blog}."
continue # Skip this file and move to the next
fi
if [[ "${title_found}" == false ]]; then
_msg debug "${0:t}_msg_10" " ${blog}."
continue # Skip this file and move to the next
fi
# Extract blog information
sdate=( $( echo ${content} | grep DATE | sed "s|DATE\ ||" | sed "s|\-|\ |g" ) )
if [[ ${generator} == "native" ]]; then
while IFS= read -r line; do
if [[ "$line" == "BLOG_TITLE "* ]]; then
btitle="${line#BLOG_TITLE }"
break
fi
done <<< "$content"
elif [[ ${generator} == "markdown" ]]; then
while IFS= read -r line; do
if [[ "$line" == \#* ]]; then
btitle="${line#\#}" # Remove the first '#' character
btitle="${btitle#\#}" # Remove the second '#' character if present
btitle="${btitle#"${btitle%%[![:space:]]*}"}" # Trim leading whitespace
break # Exit the loop after finding the first heading
fi
done <<< "$content"
fi
ingress=$( echo ${content} | sed "s/'/\\\'/g" | xargs | grep -Po "#INGRESS_START\K(.*?)#INGRESS_STOP" | sed "s|\ \#INGRESS_STOP||" | sed "s|^\ ||" )
body=$( echo ${content} | sed "s/'/\\\'/g" | xargs | grep -Po "#BODY_START\K(.*?)#BODY_STOP" | sed "s|\ \#BODY_STOP||" | sed "s|^\ ||" )
blog_index=$(echo "${btitle:l}" | sed 's/ /_/g; s/,//g; s/\.//g; s/://g; s/[()]//g')
blog_dir="/blog/${sdate[2]}/${sdate[3]:l}/${sdate[4]}"
blog_url="${blog_dir}/${blog_index}.html"
if (${debug}) _msg debug "${0:t}_msg_11" " ${blog} " "${0:t}_msg_11.1"
# Concatenate all metadata into a single string for the current blog
local metadata_str="SDATE: ${sdate[@]}||BTITLE: ${btitle}||INGRESS: ${ingress}||URL: ${blog_url}"
# Append this metadata string to the array
BLOG_META_STR_ARRAY+=("${metadata_str}")
if (${debug}) _msg debug "${0:t}_msg_12" " ${blog}"
_msg std " - ${blog_index}.html"
# Prepare the blog template
if (${debug}) _msg debug "${0:t}_msg_14" " ${blog}"
local blog_content=$(
echo "${blog_tpl}" | \
perl -pe "\
s|BLOGTITLE|${btitle}|g; \
s|BLOGURL|${blog_url}|g; \
s|\QINGRESS\E|${ingress}|g; \
s|\QBODY\E|${body}|g \
")
blog_content="${blog_content//CALNDAY/${sdate[4]}}"
blog_content="${blog_content//CALYEAR/${sdate[2]}}"
blog_content="${blog_content//CALMONTH/${sdate[3]}}"
blog_content="${blog_content//CALADAY/${sdate[1]}}"
if (${debug}) _msg debug "${0:t}_msg_15" " ${blog}"
if [[ ${generator} == "native" ]]; then
blog_content=$( ${engine} "${blog_content}" )
# Look for links, images and videos and convert them if present.
if (${debug}) _msg debug "${0:t}_msg_16"
if [[ $( echo ${blog_content} | grep \#link ) ]]; then
if (${debug}) _msg debug "${0:t}_msg_17"
blog_content=$(_link "${blog_content}")
fi
if [[ $( echo ${blog_content} | grep \#showimg ) ]]; then
if (${debug}) _msg debug "${0:t}_msg_18"
blog_content=$(_image "${blog_content}")
fi
if [[ $( echo ${blog_content} | grep \#ytvideo ) ]]; then
if (${debug}) _msg debug "${0:t}_msg_19"
blog_content=$(_youtube "${blog_content}")
fi
elif [[ ${generator} == "markdown" ]]; then
blog_content=$(echo "$blog_content" | ${engine} ${engine_opts})
fi
# Replace every #tagline in blog_content
if (${debug}) _msg debug "${0:t}_msg_20"
blog_content=$( echo ${blog_content} | perl -pe "s|#tagline|${site_tagline}|gs; s|#sitename|${site_name}|gs; s|#pagetitle|${page_title}|gs" )
blog_content=$(_last_updated "${blog_content}")
blog_content=$(_cleanup "${blog_content}")
# Create directory if it doesn't exist
if (${debug}) _msg debug "${0:t}_msg_21" " ${www_root}${blog_dir}"
[[ ! -d "${www_root}/${blog_dir}" ]] && mkdir -p "${www_root}/${blog_dir}"
# Write to file
if (${debug}) _msg debug "${0:t}_msg_22" " ${www_root}${blog_url}"
echo "${blog_content}" > "${www_root}${blog_url}"
unset sdate btitle ingress body blog_index blog_dir blog_url
done
# Now BLOG_META_STR_ARRAY contains the metadata string for each blog post
export BLOG_META_STR_ARRAY
if (${debug}) _msg debug "${0:t}_msg_23"
export new_updated_blogs=true
else
_msg sub "${0:t}_msg_24"
export new_updated_blogs=false
fi
if [[ ${new_updated_blogs} == "true" ]]; then
if (${debug}) _msg sub "${0:t}_msg_25"
_blog_idx_for_index
if (${debug}) _msg sub "${0:t}_msg_26"
_blog_index
fi
}
function _blog_idx_for_index() {
# This function generates the file blog/index.tmp.html
local debug=${globaldebug:-false}
_msg sub "${0:t}_msg_1" " ${project_dir}/blog/index.tmp.html"
if (${debug}) _msg debug "${0:t}_msg_2"
local blog_list_tpl=$(<${project_dir}/themes/${theme}/blog_list.tpl)
# Truncate file before writing new one
: >| "${project_dir}/blog/index.tmp.html"
if (${debug}) _msg debug "${0:t}_msg_3" " ${BLOG_META_STR_ARRAY[@]}"
for meta_str in ${BLOG_META_STR_ARRAY[@]}
do
if (${debug}) _msg debug "${0:t}_msg_4"
if (${debug}) _msg debug "${0:t}_msg_5" " ${meta_str}"
# Split meta_str into individual metadata components
local -a meta_array=("${(@s/||/)meta_str}")
# Initialize variables to store each component
local sdate btitle ingress url
# Iterate over each component and extract information
if (${debug}) _msg debug "${0:t}_msg_6"
for component in "${meta_array[@]}"
do
case "${component}" in
SDATE:*) sdate=${component#SDATE: } ;;
BTITLE:*) btitle=${component#BTITLE: } ;;
INGRESS:*) ingress=${component#INGRESS: } ;;
URL:*) url=${component#URL: } ;;
esac
local adate=( $( echo ${sdate} ) )
local caladay="${adate[1]}"
local calyear="${adate[2]}"
local calmonth="${adate[3]}"
local calnday="${adate[4]}"
local bdate="${adate[1]} - ${adate[4]}/${adate[3]}/${adate[2]}"
blog_list_content=$(
echo "${blog_list_tpl}" | \
perl -pe "\
s|BLOGURL|${site_url}${url}|g; \
s|BLOGTITLE|${btitle}|g; \
s|INGRESS|${ingress}|g; \
s|BLOGDATE|${bdate}|g; \
s|CALADAY|${caladay}|g; \
s|CALNDAY|${calnday}|g; \
s|CALMONTH|${calmonth}|g; \
s|CALYEAR|${calyear}|g \
")
done
unset sdate btitle ingress url
if (${debug}) _msg debug "${0:t}_msg_7" " ${engine} " "${0:t}_msg_7.1"
blog_list_content=$( ${engine} ${blog_list_content} )
if (${debug}) _msg debug "${0:t}_msg_8" " ${project_dir}/blog/index.tmp.html"
if (${debug}) _msg debug "${0:t}_msg_9" " ${blog_list_content}"
echo ${blog_list_content} >> ${project_dir}/blog/index.tmp.html
done
}
function _blog_index() {
local debug=${globaldebug:-false}
# This function generates the www_root/blog/index.html file that gets its data from _blog_list_for_index()
# ${new_updated_blogs} comes from the function _blogs if anything new or updated is detected
if [[ ${blog_in_index} == "false" ]] && [[ ${new_updated_blogs} = "true" ]]; then
if (${debug}) _msg debug "${0:t}_msg_1" "${blog_in_index}"
if (${debug}) _msg debug "${0:t}_msg_2" "${new_updated_blogs}"
if (${debug}) _msg debug "${0:t}_msg_3"
if (${debug}) _msg debug "${0:t}_msg_4" " ${blog_in_index}"
_msg std "${0:t}_msg_5" " ${www_root}/blog/index.html"
local blog_index_tpl=$(<${project_dir}/themes/${theme}/blog_index.tpl)
local blog_index_list=$(<${project_dir}/blog/index.tmp.html)
if (${debug}) _msg debug "${0:t}_msg_6"
local blog_index_content=$(echo "${blog_index_tpl}" | perl -pe "s|#sitename|${site_name}|gs; s|#tagline|${site_tagline}|gs")
if (${debug}) _msg debug "${0:t}_msg_7" " ${project_dir}/blog/index.tmp.html"
blog_index_content=$( awk -v new_body="$blog_index_list" '{sub(/BODY/, new_body)} 1' <(echo "${blog_index_content}") )
if (${debug}); then
_msg debug "${0:t}_msg_8" " ${www_root}/blog/index.html"
_msg debug "${0:t}_msg_9" " ${#blog_index_content}"
fi
echo "$blog_index_content" > ${www_root}/blog/index.html
_f_last_updated ${www_root}/blog/index.html
fi
}
function _add_blog_list_to_index() {
local debug=${globaldebug:-false}
# Let's find the file 'index.qst' and add the blog if blog_in_index is true
if (${debug}) _msg debug "${0:t}_msg_1"
local blog_index_list=$(<${project_dir}/blog/index.tmp.html)
local site_index_file=$(<${www_root}/index.html)
echo "${site_index_file}" | awk -v new_body="${blog_index_list}" '{sub(/BLOGINDEX/, new_body)} 1' > "${www_root}/index.html"
}
function _sitemap() {
local debug=${globaldebug:-false}
# Check if sitemap is set to true and if there are updated Blogs or Pages before updating the sitemap.xml file.
if [[ ${sitemap} == "true" ]] && ( [[ ${new_updated_blogs} == "true" ]] || [[ ${new_updated_pages} == "true" ]] ); then
_msg main "${0:t}_msg_1"
local sitemap_file="${www_root}/sitemap.xml"
# Find all HTML files and store them in an array
local -a html_files=("${(@f)$(find "${www_root}" -type f -name "*.html")}")
# Start of the XML file
echo '' > ${sitemap_file}
echo "" >> ${sitemap_file}
echo "" >> ${sitemap_file}
echo '
\n",
"#BD", "", "#EBD", "",
"#I", "", "#EI", "\n",
"#P", "
", "#EP", "
\n", "#Q", "", "#EQ", "\n", "#C", "
", "#EC", "
\n",
"#H1", "" "#EP" "
\n" "#Q" "" "#EQ" "\n" "#C" "
" "#EC" "
\n"
"#H1" "