website-htmx-rustelo-code/scripts/content/generate-content.nu

376 lines
14 KiB
Text
Raw Permalink Normal View History

2026-07-10 03:44:13 +01:00
#!/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<string>] {
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
}
}