Hugo Bases Skill
Create and edit Obsidian Bases (.base files) specifically designed for managing Hugo blog content. This skill extends standard bases functionality with Hugo-specific formulas, filters, and views.
Workflow
- Create the .base file in your content directory with Hugo-specific filters
- Define content scope using filters for posts, drafts, imported notes, etc.
- Add Hugo formulas for publishing status, content analysis, and import tracking
- Configure views for editorial dashboard, content planning, and import monitoring
- Validate that TOML frontmatter is properly parsed (requires YAML compatibility)
- Monitor content lifecycle from import to publication
Hugo-Specific Filters
Content Type Filters
filters:
and:
- 'file.ext == "md"'
- file.inFolder("content")
# Only blog posts
filters:
and:
- file.inFolder("content/Postagens")
- 'file.ext == "md"'
# Only imported notes
filters:
and:
- file.inFolder("content/notas")
- 'file.ext == "md"'
# Drafts vs Published
filters:
and:
- 'draft == true' # Only drafts
# OR
- 'draft != true' # Only published
# By publication date
filters:
and:
- 'date > "2024-01-01"'
- 'date < "2024-12-31"'
Import Status Filters
# Pending imports
filters:
and:
- file.inFolder("content/importando-vaults")
# Recently imported
filters:
and:
- file.inFolder("content/notas")
- '(now() - file.mtime).days < 30'
Hugo-Specific Formulas
Publishing Status
formulas:
status_publicacao: 'if(draft, "Rascunho", "Publicado")'
# Import status tracking
status_importacao: 'if(file.inFolder("content/importando-vaults"), "Pendente", if(file.inFolder("content/notas"), "Importado", "Nativo"))'
# Days since publication
dias_desde_publicacao: 'if(draft, "", (now() - date(date)).days)'
# Content maturity
maturidade: 'if(file.inFolder("content/Postagens"), "Blog Post", if(file.inFolder("content/notas"), "Nota", "Outro"))'
Content Analysis
formulas:
# Reading time estimation (Portuguese average)
tempo_leitura: '(file.size / 1000).round(0).toString() + " min"'
# Word count estimation
palavras_estimadas: '(file.size / 5).round(0)'
# Content size in KB
tamanho_kb: '(file.size / 1024).round(1)'
# Age in days
idade_conteudo: '(now() - file.ctime).days'
# Last updated
atualizado_recentemente: 'if((now() - file.mtime).days < 7, "Sim", "Não")'
SEO and Tags
formulas:
# Tag count
numero_tags: 'if(tags, tags.length, 0)'
# Primary tag (first tag)
tag_principal: 'if(tags && tags.length > 0, tags[0], "sem-tag")'
# Has description for SEO
tem_descricao: 'if(description, "Sim", "Não")'
# Content quality score
score_qualidade: 'numero_tags * 2 + if(description, 5, 0) + if(file.size > 2000, 3, 1)'
Import Tracking
formulas:
# Pattern detection for imports
padrao_origem: 'if(file.inFolder("content/importando-vaults"), if(file.basename.match(/^\d{4}-\d{2}-\d{2}/), "Diário", if(title.includes("INDEX") || title.includes("prompts"), "Pseudo-YAML", "Simples")), "Hugo Nativo")'
# Priority for import
prioridade_importacao: 'if(file.size > 2000, "Alta", if(file.size > 1000, "Média", "Baixa"))'
# Conversion difficulty
dificuldade_conversao: 'if(file.path.includes("wikilink") || file.path.includes("[["), "Complexa", "Simples")'
Date Formatting
formulas:
# Format publication date
data_formatada: 'if(date, date(date).format("DD/MM/YYYY"), "")'
# Year for grouping
ano_publicacao: 'if(date, date(date).year, "")'
# Month for analysis
mes_publicacao: 'if(date, date(date).format("YYYY-MM"), "")'
# Day of week
dia_semana: 'if(date, date(date).format("dddd"), "")'
Hugo Dashboard Examples
Editorial Dashboard
filters:
and:
- file.inFolder("content")
- 'file.ext == "md"'
formulas:
status_publicacao: 'if(draft, "Rascunho", "Publicado")'
tempo_leitura: '(file.size / 1000).round(0).toString() + " min"'
prioridade_edicao: 'if(draft && file.size > 1000, "Alta", if(draft, "Média", "Publicado"))'
views:
- type: table
name: "Rascunhos para Revisar"
filters:
and:
- 'draft == true'
order:
- file.name
- formula.tempo_leitura
- formula.prioridade_edicao
- file.mtime
groupBy:
property: formula.prioridade_edicao
direction: DESC
- type: table
name: "Publicados Recentemente"
filters:
and:
- 'draft != true'
- '(now() - date(date)).days < 30'
order:
- date
- file.name
- formula.tempo_leitura
Import Monitoring Dashboard
filters:
and:
- 'file.ext == "md"'
- file.inFolder("content")
formulas:
status_importacao: 'if(file.inFolder("content/importando-vaults"), "Pendente", if(file.inFolder("content/notas"), "Importado", "Nativo"))'
padrao_origem: 'if(file.inFolder("content/importando-vaults"), if(file.basename.match(/^\d{4}-\d{2}-\d{2}/), "Diário", "Texto"), "Hugo")'
prioridade_importacao: 'if(file.size > 2000, "Alta", if(file.size > 1000, "Média", "Baixa"))'
tamanho_kb: '(file.size / 1024).round(1)'
views:
- type: table
name: "Importações Pendentes"
filters:
and:
- 'formula.status_importacao == "Pendente"'
order:
- formula.prioridade_importacao
- file.name
- formula.tamanho_kb
groupBy:
property: formula.padrao_origem
direction: ASC
summaries:
formula.tamanho_kb: Sum
- type: cards
name: "Status Geral"
order:
- formula.status_importacao
- file.name
- formula.tamanho_kb
groupBy:
property: formula.status_importacao
direction: ASC
Content Analysis Dashboard
filters:
and:
- file.inFolder("content/Postagens")
- 'file.ext == "md"'
formulas:
tempo_leitura: '(file.size / 1000).round(0)'
numero_tags: 'if(tags, tags.length, 0)'
ano_publicacao: 'if(date, date(date).year, "")'
popularidade_estimada: 'numero_tags * tempo_leitura'
views:
- type: table
name: "Posts por Ano"
order:
- formula.ano_publicacao
- date
- file.name
- formula.tempo_leitura
groupBy:
property: formula.ano_publicacao
direction: DESC
summaries:
formula.tempo_leitura: Sum
- type: table
name: "Análise de Tags"
order:
- formula.numero_tags
- file.name
- formula.tempo_leitura
summaries:
formula.numero_tags: Average
formula.tempo_leitura: Average
SEO Dashboard
filters:
and:
- file.inFolder("content/Postagens")
- 'draft != true'
formulas:
tem_descricao: 'if(description, "✅", "❌")'
numero_tags: 'if(tags, tags.length, 0)'
tamanho_adequado: 'if(file.size > 1500, "✅", "❌")'
score_seo: 'if(description, 3, 0) + numero_tags + if(file.size > 1500, 2, 0)'
properties:
formula.tem_descricao:
displayName: "Descrição"
formula.tamanho_adequado:
displayName: "Tamanho OK"
formula.score_seo:
displayName: "Score SEO"
views:
- type: table
name: "SEO Check"
order:
- file.name
- formula.tem_descricao
- formula.numero_tags
- formula.tamanho_adequado
- formula.score_seo
summaries:
formula.score_seo: Average
Hugo-Specific Considerations
TOML vs YAML Compatibility
⚠️ Important: Obsidian Bases expect YAML frontmatter (---), but Hugo uses TOML (+++). For bases to read Hugo frontmatter properly:
- Convert key posts to YAML frontmatter for analysis
- Use file-based formulas (
file.size,file.mtime) which always work - Create separate analysis notes with YAML if needed for detailed property analysis
Working with Hugo Structure
# Target specific content types
filters:
or:
- file.inFolder("content/Postagens") # Blog posts
- file.inFolder("content/Portfólio") # Portfolio
- file.inFolder("content/notas") # Imported notes
# Exclude build artifacts
filters:
not:
- file.inFolder("public")
- file.inFolder(".hugo_build.lock")
Performance Tips
- Limit scope to specific folders to improve performance
- Use file-based formulas when possible (more reliable)
- Cache results by saving base views as regular notes when needed
Integration with Import Workflow
Before Import
# Monitor pending imports
filters:
and:
- file.inFolder("content/importando-vaults")
formulas:
estimated_work: 'if(file.size > 2000, "30 min", if(file.size > 1000, "15 min", "5 min"))'
After Import
# Track recent imports
filters:
and:
- file.inFolder("content/notas")
- '(now() - file.mtime).days < 7'
formulas:
needs_review: 'if(file.path.includes("wikilink"), "Sim", "Não")'