website-htmx-rustelo-code/scripts/others/populate-content-indices-simple.sh
2026-07-10 03:44:13 +01:00

195 lines
No EOL
5.9 KiB
Bash
Executable file
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# Simple script to populate content index.json files from existing markdown files
set -e
# Colors
GREEN='\033[0;32m'
BLUE='\033[0;34m'
NC='\033[0m'
log_info() { echo -e "${BLUE} $1${NC}"; }
log_success() { echo -e "${GREEN}$1${NC}"; }
# Function to extract value from YAML frontmatter
get_yaml_value() {
local file="$1"
local key="$2"
# Extract frontmatter and get the value
awk '/^---$/{if(p==1){exit} p++; next} p==1 && /^'$key':/ {gsub(/^'$key': */, ""); gsub(/^"/, ""); gsub(/"$/, ""); print}' "$file"
}
# Function to extract tags array from YAML
get_yaml_tags() {
local file="$1"
# Extract tags array - handle both inline and multiline formats
awk '/^---$/{if(p==1){exit} p++; next}
p==1 && /^tags:/ {
if(/\[.*\]/) {
# Inline array format: tags: ["tag1", "tag2"]
gsub(/^tags: *\[/, ""); gsub(/\].*$/, ""); gsub(/"/, ""); gsub(/, */, "\",\"");
if(length($0) > 0) print "\"" $0 "\""
} else {
# Multiline format - skip for now, would need more complex parsing
next
}
}' "$file"
}
# Function to process a single markdown file
process_markdown_file() {
local md_file="$1"
local content_type="$2"
local language="$3"
# Extract values
local id=$(get_yaml_value "$md_file" "id")
local title=$(get_yaml_value "$md_file" "title")
local slug=$(get_yaml_value "$md_file" "slug")
local excerpt=$(get_yaml_value "$md_file" "excerpt")
local date=$(get_yaml_value "$md_file" "date")
local read_time=$(get_yaml_value "$md_file" "read_time")
local featured=$(get_yaml_value "$md_file" "featured")
local category=$(get_yaml_value "$md_file" "category")
local tags=$(get_yaml_tags "$md_file")
# Defaults
id=${id:-$(basename "$md_file" .md)}
slug=${slug:-$id}
title=${title:-"Untitled"}
excerpt=${excerpt:-""}
date=${date:-$(date +"%Y-%m-%d")}
read_time=${read_time:-"5 min read"}
featured=${featured:-false}
# Infer category from directory if not set
if [ -z "$category" ]; then
local dir_name=$(basename "$(dirname "$md_file")")
if [ "$dir_name" != "$language" ]; then
category="$dir_name"
fi
fi
# Build categories array
local categories=""
if [ -n "$category" ]; then
categories="\"$category\""
fi
# Build tags array
if [ -z "$tags" ]; then
tags=""
fi
# Build source_file path (relative to content root, includes category directory)
# Use basename and dirname to manually construct the relative path since macOS realpath doesn't have --relative-to
local file_dir=$(dirname "$md_file")
local content_relative_dir=${file_dir#content/}
local filename=$(basename "$md_file")
local relative_path="$content_relative_dir/$filename"
# Create JSON using jq for safety
jq -n \
--arg id "$id" \
--arg title "$title" \
--arg slug "$slug" \
--arg language "$language" \
--arg content_type "$content_type" \
--argjson categories "[$categories]" \
--argjson tags "[$tags]" \
--argjson featured "$featured" \
--arg excerpt "$excerpt" \
--arg content "" \
--arg created_at "$date" \
--arg read_time "$read_time" \
--arg source_file "$relative_path" \
'{
id: $id,
title: $title,
slug: $slug,
language: $language,
content_type: $content_type,
categories: $categories,
tags: $tags,
emoji: null,
featured: $featured,
excerpt: $excerpt,
content: $content,
created_at: $created_at,
updated_at: null,
read_time: $read_time,
source_file: $source_file
}'
}
# Function to process content type and language
process_content_lang() {
local content_type="$1"
local language="$2"
local lang_dir="content/${content_type}/${language}"
if [ ! -d "$lang_dir" ]; then
return
fi
log_info "Processing $content_type/$language"
# Start with empty array
echo "[]" > "/tmp/${content_type}_${language}.json"
# Process each markdown file
local count=0
find "$lang_dir" -name "*.md" -type f | while read -r md_file; do
log_info " Processing: $(basename "$md_file")"
# Generate entry and add to array
local entry=$(process_markdown_file "$md_file" "$content_type" "$language")
echo "$entry" > "/tmp/current_entry.json"
# Add to main array
jq '. += [inputs]' "/tmp/${content_type}_${language}.json" "/tmp/current_entry.json" > "/tmp/${content_type}_${language}_new.json"
mv "/tmp/${content_type}_${language}_new.json" "/tmp/${content_type}_${language}.json"
count=$((count + 1))
done
# Create final index file
local index_file="${lang_dir}/index.json"
local entries=$(cat "/tmp/${content_type}_${language}.json")
cat > "$index_file" << EOF
{
"$content_type": $entries,
"language": "$language"
}
EOF
local final_count=$(jq length "/tmp/${content_type}_${language}.json")
log_success "Created $content_type/$language index with $final_count entries"
# Cleanup temp files
rm -f "/tmp/${content_type}_${language}.json" "/tmp/current_entry.json"
}
# Main execution
log_info "Populating content indices..."
# Check for jq
if ! command -v jq &> /dev/null; then
echo "❌ jq is required but not installed"
exit 1
fi
# Process blog content
process_content_lang "blog" "en"
process_content_lang "blog" "es"
# Process recipes content
process_content_lang "recipes" "en"
process_content_lang "recipes" "es"
log_success "Content indices populated successfully!"
log_info "Run 'just dev' to rebuild and embed the new indices."