#!/usr/bin/env nu # Content Generation Script # Nushell version of generate-content.sh # Generates new content files from templates with proper localization def main [command?: string, ...args] { # Configuration let config = { content_dir: ($env.SITE_CONTENT_PATH? | default "site/content"), templates_dir: "scripts/content/templates", languages: ["en", "es"] } print $"(ansi blue)📝 Content Generation Tool(ansi reset)" if ($command | is-empty) { show_generate_usage exit 0 } match $command { "blog-post" => { let parsed = parse_content_args $args generate_blog_post $config $parsed } "recipe" | "prescription" => { let parsed = parse_content_args $args generate_recipe $config $parsed } "templates" => { create_templates $config } "index" => { update_indices $config } "help" | "-h" | "--help" => { show_generate_usage } _ => { print $"(ansi red)❌ Unknown command: ($command)(ansi reset)" show_generate_usage exit 1 } } } # Show usage information def show_generate_usage [] { print "================================" print "" print "Usage: nu generate-content.nu [COMMAND] [OPTIONS]" print "" print "Commands:" print " blog-post Generate a new blog post" print " recipe Generate a new recipe/prescription" print " templates Create/update content templates" print " index Update all content indices" print " help Show this help message" print "" print "Options:" print " --title TITLE Content title (required)" print " --category CATEGORY Content category" print " --author AUTHOR Content author" print " --tags TAG1,TAG2 Comma-separated tags" print " --difficulty LEVEL Recipe difficulty (Beginner|Intermediate|Advanced)" print " --lang LANGUAGE Target language (en|es|all) [default: all]" print " --description DESC Short description" print " --published BOOL Published status [default: true]" print "" print "Examples:" print " nu generate-content.nu blog-post --title \"My New Post\" --category \"Technology\"" print " nu generate-content.nu recipe --title \"Docker Setup\" --category \"DevOps\" --difficulty \"Intermediate\"" print " nu generate-content.nu templates" print " nu generate-content.nu index" } # Parse content generation arguments def parse_content_args [args: list] { mut parsed = { title: "", category: "", author: "", tags: [], difficulty: "", language: "all", description: "", published: "true" } mut i = 0 while $i < ($args | length) { let arg = ($args | get $i) match $arg { "--title" => { $i = $i + 1 if $i < ($args | length) { $parsed = ($parsed | upsert title ($args | get $i)) } } "--category" => { $i = $i + 1 if $i < ($args | length) { $parsed = ($parsed | upsert category ($args | get $i)) } } "--author" => { $i = $i + 1 if $i < ($args | length) { $parsed = ($parsed | upsert author ($args | get $i)) } } "--tags" => { $i = $i + 1 if $i < ($args | length) { let tags_str = ($args | get $i) $parsed = ($parsed | upsert tags ($tags_str | split row "," | each { |tag| $tag | str trim })) } } "--difficulty" => { $i = $i + 1 if $i < ($args | length) { $parsed = ($parsed | upsert difficulty ($args | get $i)) } } "--lang" => { $i = $i + 1 if $i < ($args | length) { $parsed = ($parsed | upsert language ($args | get $i)) } } "--description" => { $i = $i + 1 if $i < ($args | length) { $parsed = ($parsed | upsert description ($args | get $i)) } } "--published" => { $i = $i + 1 if $i < ($args | length) { $parsed = ($parsed | upsert published ($args | get $i)) } } } $i = $i + 1 } $parsed } # Generate a new blog post def generate_blog_post [config, options] { if ($options.title | is-empty) { print $"(ansi red)❌ Title is required for blog posts(ansi reset)" exit 1 } print $"(ansi blue)🔧 Generating blog post: ($options.title)(ansi reset)" # Generate slug from title let slug = ($options.title | str downcase | str replace -a " " "-" | str replace -a "[^a-z0-9-]" "") let current_date = (date now | format date "%Y-%m-%d") # Determine target languages let languages = if $options.language == "all" { $config.languages } else { [$options.language] } for lang in $languages { let blog_dir = $"($config.content_dir)/blog/($lang)" mkdir $blog_dir let file_path = $"($blog_dir)/($slug).md" if ($file_path | path exists) { print $"(ansi yellow)⚠️ Blog post already exists: ($file_path)(ansi reset)" continue } # Create blog post content let frontmatter = create_blog_frontmatter $options $current_date let content_body = get_blog_template_body $lang let full_content = $"---\n($frontmatter)\n---\n\n($content_body)" $full_content | save $file_path print $"(ansi green)✅ Created blog post: ($file_path)(ansi reset)" } print $"(ansi green)🎉 Blog post generation completed!(ansi reset)" } # Generate a new recipe/prescription def generate_recipe [config, options] { if ($options.title | is-empty) { print $"(ansi red)❌ Title is required for recipes(ansi reset)" exit 1 } print $"(ansi blue)🔧 Generating recipe: ($options.title)(ansi reset)" # Generate slug from title let slug = ($options.title | str downcase | str replace -a " " "-" | str replace -a "[^a-z0-9-]" "") let current_date = (date now | format date "%Y-%m-%d") # Determine target languages let languages = if $options.language == "all" { $config.languages } else { [$options.language] } for lang in $languages { let recipes_dir = $"($config.content_dir)/recipes/($lang)" mkdir $recipes_dir let file_path = $"($recipes_dir)/($slug).md" if ($file_path | path exists) { print $"(ansi yellow)⚠️ Recipe already exists: ($file_path)(ansi reset)" continue } # Create recipe content let frontmatter = create_recipe_frontmatter $options $current_date let content_body = get_recipe_template_body $lang let full_content = $"---\n($frontmatter)\n---\n\n($content_body)" $full_content | save $file_path print $"(ansi green)✅ Created recipe: ($file_path)(ansi reset)" } print $"(ansi green)🎉 Recipe generation completed!(ansi reset)" } # Create blog post frontmatter def create_blog_frontmatter [options, date: string] { mut frontmatter = $"title: \"($options.title)\"\n" $frontmatter = $frontmatter + $"date: \"($date)\"\n" if not ($options.author | is-empty) { $frontmatter = $frontmatter + $"author: \"($options.author)\"\n" } if not ($options.category | is-empty) { $frontmatter = $frontmatter + $"category: \"($options.category)\"\n" } if not ($options.description | is-empty) { $frontmatter = $frontmatter + $"description: \"($options.description)\"\n" } if ($options.tags | length) > 0 { let tags_str = ($options.tags | each { |tag| $"\"($tag)\"" } | str join ", ") $frontmatter = $frontmatter + $"tags: [($tags_str)]\n" } $frontmatter = $frontmatter + $"published: ($options.published)\n" $frontmatter } # Create recipe frontmatter def create_recipe_frontmatter [options, date: string] { mut frontmatter = $"title: \"($options.title)\"\n" $frontmatter = $frontmatter + $"date: \"($date)\"\n" if not ($options.author | is-empty) { $frontmatter = $frontmatter + $"author: \"($options.author)\"\n" } if not ($options.category | is-empty) { $frontmatter = $frontmatter + $"category: \"($options.category)\"\n" } if not ($options.description | is-empty) { $frontmatter = $frontmatter + $"description: \"($options.description)\"\n" } if not ($options.difficulty | is-empty) { $frontmatter = $frontmatter + $"difficulty: \"($options.difficulty)\"\n" } if ($options.tags | length) > 0 { let tags_str = ($options.tags | each { |tag| $"\"($tag)\"" } | str join ", ") $frontmatter = $frontmatter + $"tags: [($tags_str)]\n" } $frontmatter = $frontmatter + $"published: ($options.published)\n" $frontmatter } # Get blog template body def get_blog_template_body [lang: string] { if $lang == "es" { "# Introducción\n\nEscribe tu introducción aquí...\n\n## Desarrollo\n\nDesarrolla tu contenido aquí...\n\n## Conclusión\n\nConclusiones y reflexiones finales...\n" } else { "# Introduction\n\nWrite your introduction here...\n\n## Main Content\n\nDevelop your content here...\n\n## Conclusion\n\nConclusions and final thoughts...\n" } } # Get recipe template body def get_recipe_template_body [lang: string] { if $lang == "es" { "# Descripción\n\nBreve descripción de esta receta técnica...\n\n## Prerrequisitos\n\n- Prerrequisito 1\n- Prerrequisito 2\n\n## Pasos\n\n### Paso 1: Preparación\n\n```bash\n# Comandos aquí\n```\n\n### Paso 2: Implementación\n\n```bash\n# Más comandos\n```\n\n## Verificación\n\nCómo verificar que todo funciona correctamente...\n\n## Recursos Adicionales\n\n- [Enlace 1](https://ontoref.dev)\n- [Enlace 2](https://ontoref.dev)\n" } else { "# Description\n\nBrief description of this technical recipe...\n\n## Prerequisites\n\n- Prerequisite 1\n- Prerequisite 2\n\n## Steps\n\n### Step 1: Preparation\n\n```bash\n# Commands here\n```\n\n### Step 2: Implementation\n\n```bash\n# More commands\n```\n\n## Verification\n\nHow to verify everything works correctly...\n\n## Additional Resources\n\n- [Link 1](https://ontoref.dev)\n- [Link 2](https://ontoref.dev)\n" } } # Create/update content templates def create_templates [config] { print $"(ansi blue)🔧 Creating/updating content templates...(ansi reset)" mkdir $config.templates_dir # Create blog post template JSON let blog_template_json = { type: "blog-post", required_fields: ["title", "date"], optional_fields: ["author", "category", "description", "tags", "published"], frontmatter_template: { title: "{{ title }}", date: "{{ date }}", author: "{{ author }}", category: "{{ category }}", description: "{{ description }}", tags: ["{{ tags }}"], published: true } } $blog_template_json | to json | save $"($config.templates_dir)/content-post.json" # Create recipe template JSON let recipe_template_json = { type: "recipe", required_fields: ["title", "date"], optional_fields: ["author", "category", "description", "difficulty", "tags", "published"], frontmatter_template: { title: "{{ title }}", date: "{{ date }}", author: "{{ author }}", category: "{{ category }}", description: "{{ description }}", difficulty: "{{ difficulty }}", tags: ["{{ tags }}"], published: true } } $recipe_template_json | to json | save $"($config.templates_dir)/recipe.json" # Create markdown templates let blog_template_md = "---\ntitle: \"{{ title }}\"\ndate: \"{{ date }}\"\nauthor: \"{{ author }}\"\ncategory: \"{{ category }}\"\ndescription: \"{{ description }}\"\ntags: [{{ tags }}]\npublished: {{ published }}\n---\n\n# Introduction\n\nWrite your introduction here...\n\n## Main Content\n\nDevelop your content here...\n\n## Conclusion\n\nConclusions and final thoughts...\n" $blog_template_md | save $"($config.templates_dir)/content-post.md" let recipe_template_md = "---\ntitle: \"{{ title }}\"\ndate: \"{{ date }}\"\nauthor: \"{{ author }}\"\ncategory: \"{{ category }}\"\ndescription: \"{{ description }}\"\ndifficulty: \"{{ difficulty }}\"\ntags: [{{ tags }}]\npublished: {{ published }}\n---\n\n# Description\n\nBrief description of this technical recipe...\n\n## Prerequisites\n\n- Prerequisite 1\n- Prerequisite 2\n\n## Steps\n\n### Step 1: Preparation\n\n```bash\n# Commands here\n```\n\n### Step 2: Implementation\n\n```bash\n# More commands\n```\n\n## Verification\n\nHow to verify everything works correctly...\n\n## Additional Resources\n\n- [Link 1](https://ontoref.dev)\n- [Link 2](https://ontoref.dev)\n" $recipe_template_md | save $"($config.templates_dir)/recipe.md" print $"(ansi green)✅ Templates created in ($config.templates_dir)(ansi reset)" } # Update all content indices def update_indices [config] { print $"(ansi blue)🔧 Updating all content indices...(ansi reset)" try { nu scripts/content/content-manager.nu generate-indices print $"(ansi green)🎉 All indices updated successfully!(ansi reset)" } catch { print $"(ansi red)❌ Failed to update indices(ansi reset)" exit 1 } }