376 lines
No EOL
14 KiB
Text
Executable file
376 lines
No EOL
14 KiB
Text
Executable file
#!/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
|
|
}
|
|
} |