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

209 lines
No EOL
6.6 KiB
Bash
Executable file
Raw Permalink 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
# Populate content index.json files from existing markdown files
# This script scans all markdown files in content directories and creates proper JSON index files
set -e
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
log_info() { echo -e "${BLUE} $1${NC}"; }
log_success() { echo -e "${GREEN}$1${NC}"; }
log_warning() { echo -e "${YELLOW}⚠️ $1${NC}"; }
CONTENT_DIR="content"
TEMP_DIR="/tmp/content-indices"
# Create temp directory
mkdir -p "$TEMP_DIR"
# Function to extract YAML frontmatter from markdown file
extract_frontmatter() {
local file="$1"
awk '/^---$/{p++} p==1 && !/^---$/ {print} p==2{exit}' "$file"
}
# Function to parse YAML value
parse_yaml_value() {
local file="$1"
local key="$2"
extract_frontmatter "$file" | grep "^${key}:" | sed "s/^${key}: *//g" | sed 's/^"//g' | sed 's/"$//g' | head -1
}
# Function to parse YAML array
parse_yaml_array() {
local file="$1"
local key="$2"
extract_frontmatter "$file" | sed -n "/^${key}:/,/^[^ ]/p" | grep "^ *-" | sed 's/^ *- *//g' | sed 's/^"//g' | sed 's/"$//g' | tr '\n' ',' | sed 's/,$//g'
}
# Function to generate JSON entry from markdown file
generate_json_entry() {
local md_file="$1"
local content_type="$2"
local language="$3"
# Extract metadata
local id=$(parse_yaml_value "$md_file" "id")
local title=$(parse_yaml_value "$md_file" "title")
local slug=$(parse_yaml_value "$md_file" "slug")
local excerpt=$(parse_yaml_value "$md_file" "excerpt")
local created_at=$(parse_yaml_value "$md_file" "date")
local read_time=$(parse_yaml_value "$md_file" "read_time")
local featured=$(parse_yaml_value "$md_file" "featured")
local tags=$(parse_yaml_array "$md_file" "tags")
local categories=$(parse_yaml_array "$md_file" "categories")
# Generate ID from filename if not found in frontmatter
if [ -z "$id" ]; then
id=$(basename "$md_file" .md)
fi
# Generate slug from ID if not found
if [ -z "$slug" ]; then
slug="$id"
fi
# Default values and escape quotes for JSON
title=$(echo "${title:-Untitled}" | sed 's/"/\\"/g')
excerpt=$(echo "${excerpt:-}" | sed 's/"/\\"/g')
created_at=${created_at:-$(date +"%Y-%m-%d")}
read_time=${read_time:-"5 min read"}
featured=${featured:-false}
# Infer category from file path if not in frontmatter
if [ -z "$categories" ]; then
local dir_path=$(dirname "$md_file")
local category=$(basename "$dir_path")
if [ "$category" != "$language" ] && [ "$category" != "." ]; then
categories="$category"
fi
fi
# Format arrays for JSON
local tags_json=""
if [ -n "$tags" ]; then
tags_json="\"$(echo "$tags" | sed 's/,/","/g')\""
fi
local categories_json=""
if [ -n "$categories" ]; then
categories_json="\"$(echo "$categories" | sed 's/,/","/g')\""
fi
# Get content for full-text search (first 200 chars) and escape quotes
local content=$(tail -n +10 "$md_file" | head -c 200 | tr '\n' ' ' | sed 's/"/\\"/g')
# Use jq to create proper JSON
jq -n \
--arg id "$id" \
--arg title "$title" \
--arg slug "$slug" \
--arg language "$language" \
--arg content_type "$content_type" \
--argjson categories "[${categories_json}]" \
--argjson tags "[${tags_json}]" \
--argjson featured "$featured" \
--arg excerpt "$excerpt" \
--arg content "$content" \
--arg created_at "$created_at" \
--arg read_time "$read_time" \
'{
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
}'
}
# Function to process content type directory
process_content_type() {
local content_type="$1"
local content_type_dir="${CONTENT_DIR}/${content_type}"
if [ ! -d "$content_type_dir" ]; then
log_warning "Content type directory not found: $content_type_dir"
return
fi
log_info "Processing content type: $content_type"
# Process each language directory
for lang_dir in "$content_type_dir"/*; do
if [ -d "$lang_dir" ]; then
local language=$(basename "$lang_dir")
log_info " Processing language: $language"
local temp_entries="$TEMP_DIR/${content_type}_${language}_entries.json"
echo "[]" > "$temp_entries"
# Find all markdown files in this directory and subdirectories
find "$lang_dir" -name "*.md" -type f | while read -r md_file; do
log_info " Processing: $(basename "$md_file")"
# Generate JSON entry and save to temp file
local entry_file="$TEMP_DIR/entry_$(basename "$md_file" .md).json"
generate_json_entry "$md_file" "$content_type" "$language" > "$entry_file"
# Add to temp entries file
local temp_with_entry="$TEMP_DIR/temp_entry.json"
jq --slurpfile entry "$entry_file" '. += $entry' "$temp_entries" > "$temp_with_entry"
mv "$temp_with_entry" "$temp_entries"
rm "$entry_file"
done
# Create final index file
local index_file="${lang_dir}/index.json"
local entries=$(cat "$temp_entries")
cat > "$index_file" << EOF
{
"${content_type}": ${entries},
"language": "$language"
}
EOF
local count=$(jq "length" "$temp_entries")
log_success " Created index for $content_type/$language with $count entries"
fi
done
}
# Main execution
log_info "Starting content index population..."
# Check if content directory exists
if [ ! -d "$CONTENT_DIR" ]; then
log_warning "Content directory not found: $CONTENT_DIR"
exit 1
fi
# Check if jq is available
if ! command -v jq &> /dev/null; then
log_warning "jq is required but not installed. Please install jq."
exit 1
fi
# Process each content type
process_content_type "blog"
process_content_type "recipes"
# Cleanup
rm -rf "$TEMP_DIR"
log_success "Content index population completed!"
log_info "Run 'just dev' or rebuild the project to embed the updated indices."