#!/bin/bash # Content Migration Script - Normalize Categories, Tags, and Add Slugs # This script normalizes all content to use proper URL-safe slugs set -e CONTENT_ROOT="content" BACKUP_DIR="content-backup-$(date +%Y%m%d_%H%M%S)" echo "🔄 Starting content migration to normalize categories, tags, and add slugs" echo "📁 Content root: $CONTENT_ROOT" echo "💾 Backup will be created at: $BACKUP_DIR" # Create backup echo "📦 Creating backup..." cp -r "$CONTENT_ROOT" "$BACKUP_DIR" echo "✅ Backup created successfully" # Function to normalize text to slug format normalize_slug() { local text="$1" echo "$text" | \ sed 's/[áàäâãå]/a/g; s/[éèëê]/e/g; s/[íìïî]/i/g; s/[óòöôõ]/o/g; s/[úùüû]/u/g; s/ç/c/g; s/ñ/n/g' | \ sed 's/[ÁÀÄÂÃÅ]/A/g; s/[ÉÈËÊ]/E/g; s/[ÍÌÏÎ]/I/g; s/[ÓÒÖÔÕ]/O/g; s/[ÚÙÜÛ]/U/g; s/Ç/C/g; s/Ñ/N/g' | \ tr '[:upper:]' '[:lower:]' | \ sed 's/[^a-z0-9]/-/g' | \ sed 's/--*/-/g' | \ sed 's/^-\|-$//g' } # Function to update markdown file frontmatter update_markdown_file() { local file="$1" echo "🔄 Processing: $file" # Create temporary files local temp_file=$(mktemp) local frontmatter_file=$(mktemp) local content_file=$(mktemp) # Extract frontmatter and content awk ' BEGIN { in_frontmatter = 0; frontmatter_count = 0 } /^---$/ { frontmatter_count++; if (frontmatter_count <= 2) { in_frontmatter = (frontmatter_count == 1) ? 1 : 0; if (frontmatter_count == 1) print > "'$frontmatter_file'"; if (frontmatter_count == 2) print > "'$frontmatter_file'"; } else { print > "'$content_file'"; } next; } in_frontmatter { print > "'$frontmatter_file'" } !in_frontmatter && frontmatter_count >= 2 { print > "'$content_file'" } ' "$file" # Process frontmatter local updated_frontmatter=$(mktemp) echo "---" > "$updated_frontmatter" while IFS= read -r line; do if [[ "$line" =~ ^---$ ]]; then continue elif [[ "$line" =~ ^category:\ *\"?([^\"]+)\"?$ ]]; then local category="${BASH_REMATCH[1]}" local normalized_category=$(normalize_slug "$category") echo "category: \"$normalized_category\"" >> "$updated_frontmatter" echo " 📝 Category: '$category' → '$normalized_category'" elif [[ "$line" =~ ^tags:\ *\[(.*)\]$ ]]; then local tags_content="${BASH_REMATCH[1]}" # Parse tags and normalize them local normalized_tags="" IFS=',' read -ra TAG_ARRAY <<< "$tags_content" for tag in "${TAG_ARRAY[@]}"; do # Remove quotes and whitespace tag=$(echo "$tag" | sed 's/["\[\]]//g' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') local normalized_tag=$(normalize_slug "$tag") echo " 🏷️ Tag: '$tag' → '$normalized_tag'" if [[ -n "$normalized_tags" ]]; then normalized_tags="$normalized_tags, \"$normalized_tag\"" else normalized_tags="\"$normalized_tag\"" fi done echo "tags: [$normalized_tags]" >> "$updated_frontmatter" elif [[ "$line" =~ ^title:\ *\"?([^\"]+)\"?$ ]]; then local title="${BASH_REMATCH[1]}" echo "$line" >> "$updated_frontmatter" # Add slug field if not present if ! grep -q "^slug:" "$frontmatter_file"; then local slug=$(normalize_slug "$title") echo "slug: \"$slug\"" >> "$updated_frontmatter" echo " 🔗 Added slug: '$slug'" fi else echo "$line" >> "$updated_frontmatter" fi done < "$frontmatter_file" echo "---" >> "$updated_frontmatter" # Combine updated frontmatter with content cat "$updated_frontmatter" > "$temp_file" cat "$content_file" >> "$temp_file" # Replace original file mv "$temp_file" "$file" # Cleanup rm -f "$frontmatter_file" "$content_file" "$updated_frontmatter" echo "✅ Updated: $file" } # Function to update JSON index files update_json_index() { local file="$1" echo "🔄 Processing JSON index: $file" # Create a temporary script to process the JSON local temp_script=$(mktemp) cat > "$temp_script" << 'EOF' import json import sys import re import unicodedata def normalize_slug(text): """Normalize text to URL-safe slug format using proper Unicode normalization""" # Normalize to NFD (decomposed form) and remove combining characters (accents) normalized = unicodedata.normalize('NFD', text) no_accents = ''.join(c for c in normalized if not unicodedata.combining(c)) # Convert to lowercase, replace non-alphanumeric with dashes, collapse dashes slug = re.sub(r'[^a-zA-Z0-9]+', '-', no_accents.lower()) slug = re.sub(r'-+', '-', slug) # Collapse multiple dashes slug = slug.strip('-') # Remove leading/trailing dashes return slug def update_content_item(item): """Update a single content item (blog post or prescription)""" updated = False # Normalize category if 'category' in item and item['category']: old_category = item['category'] new_category = normalize_slug(old_category) if old_category != new_category: item['category'] = new_category print(f" 📝 Category: '{old_category}' → '{new_category}'") updated = True # Normalize tags if 'tags' in item and isinstance(item['tags'], list): old_tags = item['tags'][:] new_tags = [] for tag in old_tags: new_tag = normalize_slug(tag) new_tags.append(new_tag) if tag != new_tag: print(f" 🏷️ Tag: '{tag}' → '{new_tag}'") updated = True item['tags'] = new_tags # Add localized_slug if not present if 'localized_slug' not in item and 'title' in item: slug = normalize_slug(item['title']) item['localized_slug'] = slug print(f" 🔗 Added localized_slug: '{slug}'") updated = True return updated # Read and process JSON file with open(sys.argv[1], 'r', encoding='utf-8') as f: data = json.load(f) updated_any = False # Process blog posts if 'blog_posts' in data: for post in data['blog_posts']: if update_content_item(post): updated_any = True # Process prescriptions if 'prescriptions' in data: for prescription in data['prescriptions']: if update_content_item(prescription): updated_any = True # Write back to file if updated if updated_any: with open(sys.argv[1], 'w', encoding='utf-8') as f: json.dump(data, f, indent=2, ensure_ascii=False) f.write('\n') # Add trailing newline EOF python3 "$temp_script" "$file" rm -f "$temp_script" echo "✅ Updated: $file" } # Process all markdown files echo "🔍 Finding and processing markdown files..." find "$CONTENT_ROOT" -name "*.md" -type f | while read -r file; do update_markdown_file "$file" done # Process all JSON index files echo "🔍 Finding and processing JSON index files..." find "$CONTENT_ROOT" -name "index.json" -type f | while read -r file; do update_json_index "$file" done echo "" echo "✅ Content migration completed successfully!" echo "📁 Backup location: $BACKUP_DIR" echo "" echo "📋 Summary of changes:" echo " • Normalized all category names to lowercase with dashes" echo " • Normalized all tag names to lowercase with dashes" echo " • Added slug fields to markdown frontmatter" echo " • Added localized_slug fields to JSON index files" echo " • Removed accents and special characters from all slugs" echo "" echo "🔧 Next steps:" echo " 1. Review the changes" echo " 2. Test the application" echo " 3. Update any hardcoded category/tag references" echo " 4. If satisfied, remove the backup: rm -rf $BACKUP_DIR"