Files
claude-plugins/wordpress/skills/wp-content-seo-gate/SKILL.md
T
Claude Code 4a55d51329 feat(wordpress): EMCP Tools workflow skills + widget catalogs + pending wordpress skills
- emcp-page-building, emcp-content-ops, emcp-site-audit: EMCP Tools MCP
  workflows verified live (atomic/legacy interplay, apply-template overwrite
  risk, create-theme-template goes live immediately, false-positive malware
  pattern in scan-security, change ledger + rollback)
- elementor-pro-widgets: 30+5 native Elementor Pro widgets (curated catalog)
- elementskit-widgets / powerpack-widgets: 42 + 97 third-party widgets,
  widgetType extracted from plugin source (not guessed by convention)
- plugin.json bumped 1.2.0 -> 1.3.0, keywords + description updated
- commits pending wordpress skills already present as untracked files
  (emcp-tools, wordfence, wp-activity-log, seguranca-descomplicar,
  webp-express, wp-fastest-cache, wp-font-perf, wp-meteor,
  wp-activity-log, redis-object-cache, app-for-cloudflare) and pending
  edits (rank-math, wp-cli, wp-content-seo-gate)
2026-08-19 03:44:00 +01:00

114 lines
6.3 KiB
Markdown

---
name: wp-content-seo-gate
description: "Regras e padrões obrigatórios para geração de conteúdo WordPress com RankMath Pro. INVOCAR AUTOMATICAMENTE quando: (1) escrevendo ou revendo prompts que gerem artigos, posts, descrições de podcast ou qualquer texto para publicar em WordPress, (2) criando, modificando ou auditando sistemas/pipelines/scripts que publicam conteúdo automaticamente em WordPress (publishers, crons, geradores), (3) gerando directamente conteúdo para posts WP. Previne os erros RankMath mais comuns: slug sem focus keyword, título sem número, keyword density baixa, meta description fora do limite."
---
# WP Content SEO Gate
Aplicar ANTES de escrever prompts de geração e ANTES de implementar qualquer sistema que publique em WordPress.
## Regras Obrigatórias para Prompts de Geração
Todo o prompt que instruir um LLM a gerar conteúdo WP DEVE incluir estas regras literais:
| Campo | Regra a incluir no prompt |
|-------|--------------------------|
| `focus_keyword` | 2-5 palavras, foco no benefício/problema, não no nome da ferramenta |
| `slug` | Começar com palavras da focus_keyword (hifenado, sem acentos, ≤75 chars) |
| `rank_math_title` | 50-60 chars, contém focus_keyword E um número (ano corrente ou dado concreto: "47%", "3x") |
| `rank_math_description` | 140-160 chars, focus_keyword nos primeiros 120 chars |
| `content` | focus_keyword nos primeiros 200 chars + ≥2x no corpo + ≥1 H2/H3 com a keyword |
| `image_alt` | 40-100 chars descritivo, contém focus_keyword |
| `secondary_keywords` | 3-5 keywords complementares, cada uma ≥1x no content |
**Checklist mental no prompt (incluir literalmente):**
- [ ] focus_keyword aparece em: title, rank_math_title, rank_math_description, slug, primeiros 200 chars, ≥1 H2, ≥2x no corpo
- [ ] rank_math_title contém um número (ano ou dado concreto)
- [ ] slug começa com as palavras da focus_keyword
- [ ] ≥600 palavras (RankMath penaliza abaixo deste limite)
## Padrões Obrigatórios em Publishers/Pipelines
Todo o sistema que publica em WP via código DEVE implementar estes dois auto-fixes **depois** de receber o JSON do LLM e **antes** de publicar:
### Auto-fix 1 — Slug sem focus keyword
```python
def slugify(text: str) -> str:
text = unicodedata.normalize("NFD", text.lower())
text = "".join(c for c in text if unicodedata.category(c) != "Mn")
text = re.sub(r'[^a-z0-9\s-]', '', text)
return re.sub(r'[-\s]+', '-', text.strip()).rstrip('-')
def has_keyword_in_slug(slug: str, fk: str) -> bool:
# Match sem stopwords e sem acentos
stopwords = {"a","o","as","os","de","da","do","das","dos","e","em","no","na","nos","nas","para","por","pelo","pela"}
norm = lambda s: " ".join(t for t in slugify(s).replace("-"," ").split() if t not in stopwords)
return norm(fk) in norm(slug)
# Aplicar após generate_article():
if not has_keyword_in_slug(article['slug'], article['focus_keyword']):
fk_slug = slugify(article['focus_keyword'])
orig_words = [w for w in article['slug'].split('-') if w not in fk_slug.split('-') and len(w) > 3][:2]
article['slug'] = (fk_slug + ('-' + '-'.join(orig_words) if orig_words else ''))[:75].rstrip('-')
```
### Auto-fix 2 — Título sem número (RankMath Title Readability)
```python
import time, re
if not re.search(r'\d', article.get('rank_math_title', '')):
year = time.strftime('%Y')
t = article['rank_math_title'].rstrip()
article['rank_math_title'] = (t[:55].rstrip() + f' {year}') if len(t) > 55 else f'{t} {year}'
```
## Checklist de Validação Pré-publicação
Verificar em qualquer publisher antes do `wp post create`:
- [ ] slug contém focus_keyword (sem acentos, hifenado)
- [ ] rank_math_title tem ≥1 dígito e ≤60 chars
- [ ] rank_math_description entre 140-160 chars e com focus_keyword
- [ ] image_alt contém focus_keyword
- [ ] content ≥600 palavras
- [ ] focus_keyword nos primeiros 200 chars do content
- [ ] ≥1 H2 com a focus_keyword
- [ ] Link externo à fonte (`rel="noopener"`)
- [ ] 1-3 links internos descomplicar.pt no corpo
- [ ] Artigos da categoria **Biblioteca**: terminam sempre com secção FAQ (formato exacto na Secção 10 do PROC — não inventar outro formato, o accordion do site só reconhece formatos já mapeados)
- [ ] `content` nunca vazio — confirmar corpo real, não só os campos RankMath (já aconteceu publicar posts com meta completa e corpo vazio)
- [ ] `post_author` definido pela categoria do conteúdo, não deixado no autor por omissão (mapa categoria→autor na Secção 11 do PROC — Notícias=it, Redes Sociais/Design=juju, Tecnologia=f35, IA=maisum, Gestão/Estratégia/E-commerce=ealmeida, resto da Biblioteca=info)
## Erros RankMath mais comuns
| Erro no painel | Causa | Fix |
|----------------|-------|-----|
| "Focus Keyword not found in URL" | LLM gera slug sem a FK | Auto-fix 1 obrigatório |
| "Title doesn't contain a number" | Título sem ano/dado | Auto-fix 2 + instruir LLM |
| "FK not in first 10%" | Lead não inclui a FK | Regra de prompt: FK nos primeiros 200 chars |
| "Keyword density too low/high" | <1% ou >3% | Verificar count antes de publicar |
| SEO Score N/A no dashboard | Post criado via CLI sem Gutenberg | Usar cálculo server-side de `/seo-post` Passo 6 |
| Schema ausente no HTML | Falta `rank_math_schema_*` | Ver `/seo-post` Modo aplicar Passo 3 |
## PROC Canónico
**Ler antes de agir:** `Hub/06-Operacoes/Procedimentos/D7-Tecnologia/WordPress/PROC-Conteudo-RankMath.md` (D7-WP-RM-001)
Este PROC é a fonte única de verdade para:
- Estrutura obrigatória do conteúdo (headings, distribuição FK, elementos por tipo)
- Tabela completa de campos RankMath com valores aceitáveis
- Comandos WP-CLI exactos para aplicar meta, schema e calcular score
- Checklist de validação final (9 pontos)
- Tabela de erros comuns e resolução
Quando o detalhe de uma regra não está nesta skill, está no PROC.
## Referências Adicionais
- `/seo-post` — auditar e corrigir posts **já publicados** via WP-CLI (schema, score, OG, robots)
- `Dev/claude_automations_dev/intelligence-publisher/publisher.py` — implementação de referência dos auto-fixes
- `Dev/claude_automations_dev/intelligence-publisher/prompts/article.md` — prompt de referência para artigos de notícias
- `Hub/05-Projectos/Podcast-Descomplicar-Digital/prompts/generate-wp-description.md` — prompt de referência para posts de podcast