#!/bin/bash # Content generation script for localized blog and recipe content # Generates new content files from templates with proper localization set -e # Configuration CONTENT_DIR="content" TEMPLATES_DIR="scripts/content/templates" SUPPORTED_LANGUAGES=("en" "es") # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' CYAN='\033[0;36m' NC='\033[0m' # No Color # Helper functions log_error() { echo -e "${RED}❌ ERROR: $1${NC}" } log_warning() { echo -e "${YELLOW}⚠️ WARNING: $1${NC}" } log_success() { echo -e "${GREEN}✅ $1${NC}" } log_info() { echo -e "${BLUE}ℹ️ $1${NC}" } log_step() { echo -e "${CYAN}🔧 $1${NC}" } # Display usage information show_usage() { echo -e "${BLUE}📝 Content Generation Tool${NC}" echo "================================" echo "" echo "Usage: $0 [COMMAND] [OPTIONS]" echo "" echo "Commands:" echo " blog-post Generate a new blog post" echo " recipe Generate a new recipe" echo " templates Initialize template files" echo " index Update content indices" echo " help Show this help message" echo "" echo "Blog Post Options:" echo " --title Post title (required)" echo " --author Author name (default: 'Jesús Pérez')" echo " --category Post category" echo " --tags Comma-separated tags" echo " --featured Mark as featured (true/false)" echo " --language Target language (en/es/all)" echo "" echo "Recipe Options:" echo " --title Recipe title (required)" echo " --category Recipe category (required)" echo " --difficulty Difficulty level (Beginner/Intermediate/Advanced/Expert)" echo " --prep-time Preparation time (e.g., '30 min', '2 hours')" echo " --tags Comma-separated tags" echo " --featured Mark as featured (true/false)" echo " --language Target language (en/es/all)" echo "" echo "Examples:" echo " $0 blog-post --title 'Advanced Rust Patterns' --category 'Programming' --tags 'rust,patterns'" echo " $0 recipe --title 'Docker Security Setup' --category 'Security' --difficulty 'Advanced'" echo " $0 templates" echo "" } # Generate unique ID from title generate_id() { local title="$1" echo "$title" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-z0-9]/-/g' | sed 's/--*/-/g' | sed 's/^-\|-$//g' } # Generate current date get_current_date() { date +"%Y-%m-%d" } # Create templates directory and files create_templates() { log_step "Creating template files..." mkdir -p "$TEMPLATES_DIR" # Blog post template cat > "$TEMPLATES_DIR/blog-post.md" << 'EOF' --- id: "{{ID}}" title: "{{TITLE}}" subtitle: "{{SUBTITLE}}" excerpt: "{{EXCERPT}}" author: "{{AUTHOR}}" date: "{{DATE}}" read_time: "{{READ_TIME}}" tags: [{{TAGS}}] featured: {{FEATURED}} published: true language: "{{LANGUAGE}}" translations: [{{TRANSLATIONS}}] --- # {{TITLE}} {{SUBTITLE}} ## Introduction {{EXCERPT}} ## Content Write your blog post content here... ## Conclusion Summarize your key points here... --- *Published on {{DATE}} by {{AUTHOR}}* EOF # Recipe template cat > "$TEMPLATES_DIR/recipe.md" << 'EOF' --- id: "{{ID}}" title: "{{TITLE}}" subtitle: "{{SUBTITLE}}" excerpt: "{{EXCERPT}}" category: "{{CATEGORY}}" difficulty: "{{DIFFICULTY}}" prep_time: "{{PREP_TIME}}" tags: [{{TAGS}}] featured: {{FEATURED}} language: "{{LANGUAGE}}" translations: [{{TRANSLATIONS}}] --- # {{TITLE}} {{SUBTITLE}} ## Overview {{EXCERPT}} ## Prerequisites - List prerequisites here - Required tools and knowledge - System requirements ## Difficulty Level: {{DIFFICULTY}} **Estimated Time:** {{PREP_TIME}} ## Steps ### Step 1: Initial Setup Describe the first step... ### Step 2: Configuration Describe configuration steps... ### Step 3: Implementation Describe implementation details... ## Testing How to test the implementation... ## Troubleshooting Common issues and solutions... ## Additional Resources - Link to relevant documentation - Related recipes or articles - Community resources --- *Category: {{CATEGORY}} | Difficulty: {{DIFFICULTY}} | Time: {{PREP_TIME}}* EOF # JSON templates cat > "$TEMPLATES_DIR/blog-post.json" << 'EOF' { "id": "{{ID}}", "title": "{{TITLE}}", "subtitle": "{{SUBTITLE}}", "excerpt": "{{EXCERPT}}", "author": "{{AUTHOR}}", "date": "{{DATE}}", "read_time": "{{READ_TIME}}", "tags": [{{TAGS_JSON}}], "featured": {{FEATURED}}, "published": true, "language": "{{LANGUAGE}}", "source_file": "content/blog/{{LANGUAGE}}/{{ID}}.md", "html_file": "/blog/{{LANGUAGE}}/{{ID}}.html", "translations": [{{TRANSLATIONS_JSON}}] } EOF cat > "$TEMPLATES_DIR/recipe.json" << 'EOF' { "id": "{{ID}}", "title": "{{TITLE}}", "subtitle": "{{SUBTITLE}}", "excerpt": "{{EXCERPT}}", "category": "{{CATEGORY}}", "difficulty": "{{DIFFICULTY}}", "prep_time": "{{PREP_TIME}}", "tags": [{{TAGS_JSON}}], "featured": {{FEATURED}}, "language": "{{LANGUAGE}}", "source_file": "content/recipes/{{LANGUAGE}}/{{ID}}.md", "html_file": "/recipes/{{LANGUAGE}}/{{ID}}.html", "translations": [{{TRANSLATIONS_JSON}}] } EOF log_success "Template files created in $TEMPLATES_DIR" } # Parse command line arguments parse_args() { TITLE="" AUTHOR="Jesús Pérez" CATEGORY="" DIFFICULTY="" PREP_TIME="" TAGS="" FEATURED="false" LANGUAGE="all" SUBTITLE="" EXCERPT="" while [[ $# -gt 0 ]]; do case $1 in --title) TITLE="$2" shift 2 ;; --author) AUTHOR="$2" shift 2 ;; --category) CATEGORY="$2" shift 2 ;; --difficulty) DIFFICULTY="$2" shift 2 ;; --prep-time) PREP_TIME="$2" shift 2 ;; --tags) TAGS="$2" shift 2 ;; --featured) FEATURED="$2" shift 2 ;; --language) LANGUAGE="$2" shift 2 ;; --subtitle) SUBTITLE="$2" shift 2 ;; --excerpt) EXCERPT="$2" shift 2 ;; *) log_error "Unknown option: $1" show_usage exit 1 ;; esac done } # Convert tags to JSON array format tags_to_json() { local tags="$1" if [[ -z "$tags" ]]; then echo "" return fi echo "$tags" | sed 's/,/", "/g' | sed 's/^/"/' | sed 's/$/"/' } # Get translation languages get_translations() { local current_lang="$1" local translations="" for lang in "${SUPPORTED_LANGUAGES[@]}"; do if [[ "$lang" != "$current_lang" ]]; then if [[ -z "$translations" ]]; then translations="\"$lang\"" else translations="$translations, \"$lang\"" fi fi done echo "$translations" } # Replace template variables replace_template_vars() { local template_file="$1" local output_file="$2" local lang="$3" local id=$(generate_id "$TITLE") local date=$(get_current_date) local tags_json=$(tags_to_json "$TAGS") local translations_json=$(get_translations "$lang") # Set defaults if not provided if [[ -z "$SUBTITLE" ]]; then SUBTITLE="A comprehensive guide" fi if [[ -z "$EXCERPT" ]]; then EXCERPT="This content provides detailed information and practical examples." fi # Calculate read time (rough estimate: 200 words per minute) local read_time="5 min read" cp "$template_file" "$output_file" # Replace all template variables sed -i "s|{{ID}}|$id|g" "$output_file" sed -i "s|{{TITLE}}|$TITLE|g" "$output_file" sed -i "s|{{SUBTITLE}}|$SUBTITLE|g" "$output_file" sed -i "s|{{EXCERPT}}|$EXCERPT|g" "$output_file" sed -i "s|{{AUTHOR}}|$AUTHOR|g" "$output_file" sed -i "s|{{DATE}}|$date|g" "$output_file" sed -i "s|{{READ_TIME}}|$read_time|g" "$output_file" sed -i "s|{{CATEGORY}}|$CATEGORY|g" "$output_file" sed -i "s|{{DIFFICULTY}}|$DIFFICULTY|g" "$output_file" sed -i "s|{{PREP_TIME}}|$PREP_TIME|g" "$output_file" sed -i "s|{{TAGS}}|$TAGS|g" "$output_file" sed -i "s|{{TAGS_JSON}}|$tags_json|g" "$output_file" sed -i "s|{{FEATURED}}|$FEATURED|g" "$output_file" sed -i "s|{{LANGUAGE}}|$lang|g" "$output_file" sed -i "s|{{TRANSLATIONS}}|$(get_translations "$lang" | sed 's/"//g')|g" "$output_file" sed -i "s|{{TRANSLATIONS_JSON}}|$translations_json|g" "$output_file" } # Generate blog post generate_blog_post() { if [[ -z "$TITLE" ]]; then log_error "Title is required for blog posts" show_usage exit 1 fi local id=$(generate_id "$TITLE") local languages=("${SUPPORTED_LANGUAGES[@]}") if [[ "$LANGUAGE" != "all" ]]; then languages=("$LANGUAGE") fi log_step "Generating blog post: $TITLE" for lang in "${languages[@]}"; do local blog_dir="${CONTENT_DIR}/blog/${lang}" mkdir -p "$blog_dir" local md_file="${blog_dir}/${id}.md" local json_file="/tmp/${id}.json" # Generate markdown file replace_template_vars "$TEMPLATES_DIR/blog-post.md" "$md_file" "$lang" log_success "Created markdown file: $md_file" # Generate JSON entry replace_template_vars "$TEMPLATES_DIR/blog-post.json" "$json_file" "$lang" # Update index file local index_file="${blog_dir}/index.json" if [[ -f "$index_file" ]]; then # Add to existing index local temp_file="/tmp/blog_index_temp.json" jq --argjson new_post "$(cat "$json_file")" '.blog += [$new_post]' "$index_file" > "$temp_file" mv "$temp_file" "$index_file" else # Create new index cat > "$index_file" << EOF { "blog": [$(cat "$json_file")], "language": "$lang" } EOF fi log_success "Updated blog index for language: $lang" rm "$json_file" done log_success "Blog post '$TITLE' generated successfully!" } # Generate recipe generate_recipe() { if [[ -z "$TITLE" ]]; then log_error "Title is required for recipes" show_usage exit 1 fi if [[ -z "$CATEGORY" ]]; then log_error "Category is required for recipes" show_usage exit 1 fi # Set defaults if [[ -z "$DIFFICULTY" ]]; then DIFFICULTY="Intermediate" fi if [[ -z "$PREP_TIME" ]]; then PREP_TIME="30 min" fi local id=$(generate_id "$TITLE") local languages=("${SUPPORTED_LANGUAGES[@]}") if [[ "$LANGUAGE" != "all" ]]; then languages=("$LANGUAGE") fi log_step "Generating recipe: $TITLE" for lang in "${languages[@]}"; do local recipe_dir="${CONTENT_DIR}/recipes/${lang}" mkdir -p "$recipe_dir" local md_file="${recipe_dir}/${id}.md" local json_file="/tmp/${id}.json" # Generate markdown file replace_template_vars "$TEMPLATES_DIR/recipe.md" "$md_file" "$lang" log_success "Created markdown file: $md_file" # Generate JSON entry replace_template_vars "$TEMPLATES_DIR/recipe.json" "$json_file" "$lang" # Update index file local index_file="${recipe_dir}/index.json" if [[ -f "$index_file" ]]; then # Add to existing index local temp_file="/tmp/recipe_index_temp.json" jq --argjson new_recipe "$(cat "$json_file")" '.recipes += [$new_recipe]' "$index_file" > "$temp_file" mv "$temp_file" "$index_file" else # Create new index cat > "$index_file" << EOF { "recipes": [$(cat "$json_file")], "language": "$lang" } EOF fi log_success "Updated recipe index for language: $lang" rm "$json_file" done log_success "Recipe '$TITLE' generated successfully!" } # Update all indices update_indices() { log_step "Updating all content indices..." for lang in "${SUPPORTED_LANGUAGES[@]}"; do # Update blog index local blog_dir="${CONTENT_DIR}/blog/${lang}" local blog_index="${blog_dir}/index.json" if [[ -d "$blog_dir" ]] && [[ ! -f "$blog_index" ]]; then log_info "Creating missing blog index for language: $lang" cat > "$blog_index" << EOF { "blog": [], "language": "$lang" } EOF fi # Update recipe index local recipe_dir="${CONTENT_DIR}/recipes/${lang}" local recipe_index="${recipe_dir}/index.json" if [[ -d "$recipe_dir" ]] && [[ ! -f "$recipe_index" ]]; then log_info "Creating missing recipe index for language: $lang" cat > "$recipe_index" << EOF { "recipes": [], "language": "$lang" } EOF fi done log_success "Indices updated successfully!" } # Main function main() { local command="$1" shift case "$command" in "blog-post") parse_args "$@" generate_blog_post ;; "recipe") parse_args "$@" generate_recipe ;; "templates") create_templates ;; "index") update_indices ;; "help"|"") show_usage ;; *) log_error "Unknown command: $command" show_usage exit 1 ;; esac } # Check if templates exist, create if not if [[ ! -d "$TEMPLATES_DIR" ]] && [[ "$1" != "templates" ]] && [[ "$1" != "help" ]] && [[ "$1" != "" ]]; then log_info "Templates not found, creating them first..." create_templates fi # Run main function main "$@"