- 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)
48 KiB
name, description
| name | description |
|---|---|
| rank-math | Gestão programática do Rank Math SEO (Free e PRO) via WP-CLI em servidores CWP. Cobre auditoria SEO, meta em massa, schema markup, redirects, sitemaps, Instant Indexing, Analytics PRO, hooks/filtros, taxonomias WooCommerce, News/Video Sitemap, módulos Free vs PRO completos (image-seo, local-seo, 404-monitor, llms-txt, news-sitemap, marketplace, ai-visibility), validação e rollback. Licenciamento/ligação de conta PRO → ver `/full-cliente`. Usar quando "rank math", "seo cli", "schema markup", "redirects seo", "instant indexing", "indexnow", "seo bulk", "rankmath pro", "llms.txt", "módulos rank math". |
/rank-math — Gestão Programática Rank Math SEO via WP-CLI
Operações SEO WordPress completas via WP-CLI no servidor CWP. Free + PRO.
Manual completo: Hub/06-Operacoes/Documentacao/Manuais/WP-CLI/Rank-Math-WP-CLI-Manual-Definitivo.md
Quick Reference: Hub/06-Operacoes/Documentacao/Quick-Reference/QR-RankMath-WP-CLI.md
Pesquisa Claude: Hub/06-Operacoes/Documentacao/Manuais/WP-CLI/Rank-Math-SEO-WP-CLI-Skils-Pesquisa-Claude.md
Pesquisa Gemini: Hub/06-Operacoes/Documentacao/Manuais/WP-CLI/Rank-Math-SEO-WP-CLI-Skills-Pesquisa-Gemini.md
NotebookLM: WordPress Config CLI
Skill relacionada: /seo-post — optimizar posts individuais com pipeline completo
Contexto NotebookLM
ANTES de executar, consultar notebooks para contexto especializado:
| Notebook | ID | Consultar quando |
|---|---|---|
| WordPress e Elementor | 5be0d1a6 | Sempre |
| Marketing Digital PT | 4c595973 | Para contexto SEO |
mcp__notebooklm__notebook_query({
notebook_id: "5be0d1a6-00f2-4cd9-b835-978cb7721601",
query: "<adaptar ao contexto do pedido do utilizador>"
})
Uso
/rank-math audit SITE_PATH
/rank-math update-meta SITE_PATH
/rank-math sitemap SITE_PATH
/rank-math redirects SITE_PATH
/rank-math schema post ID SITE_PATH
/rank-math indexing SITE_PATH [URL|bulk]
/rank-math analytics SITE_PATH
/rank-math taxonomy SITE_PATH
/rank-math hooks SITE_PATH
/rank-math backup SITE_PATH
/rank-math provision SITE_PATH
Contexto CWP — sempre obrigatorio
# Formato base (PHP 8.3)
/opt/alt/php-fpm83/usr/bin/php /usr/local/bin/wp <comando> --allow-root --path=/home/USER/public_html
# Alias
wp83 <comando> --allow-root --path=/home/USER/public_html
Acesso via MCP SSH:
servidor: server.descomplicar.pt | porta: 9443 | user: root
Prefixo de tabelas: Sites podem ter prefixo custom (ex: wpah_ em vez de wp_). Detectar primeiro:
PREFIX=$(wp db prefix --allow-root --path=$PATH)
# Usar $PREFIX em todas as queries SQL: ${PREFIX}posts, ${PREFIX}postmeta, etc.
Unico comando nativo Rank Math:
wp rankmath sitemap generate --allow-root --path=$PATH
Tudo o resto usa wp post meta, wp option patch, wp eval ou wp db query.
Options com defaults: Muitas sub-keys (title_separator, strip_category_base, homepage_title, knowledgegraph_type) podem nao existir na BD se nunca foram alteradas — o Rank Math usa valores por defeito internos. wp option pluck retorna exit code 1 neste caso. Nao e erro — significa valor default.
Decision tree — qual comando usar
| Operacao | Comando |
|---|---|
| Alterar meta de 1 post | wp post meta update |
| Alterar sub-key em option serializada | wp option patch update |
| Ler sub-key de option | wp option pluck |
| Schema complexo | wp eval com PHP |
| Redirects | wp eval com \RankMath\Redirections\DB |
| Bulk simples | shell loop com wp post list | while read |
| Bulk complexo | wp eval-file com script PHP |
| SQL directo | apenas auditorias (seguido de wp cache flush) |
| Regenerar sitemap | wp rankmath sitemap generate |
| Instant Indexing | wp eval com IndexNow API ou classes RM |
| Side-effects RM | wp eval com update_option() (dispara hooks) |
1. Auditoria SEO (/rank-math audit)
Passo 1 — diagnostico rapido
PATH=/home/USER/public_html
PREFIX=$(wp db prefix --allow-root --path=$PATH)
# Posts sem titulo SEO
wp db query "SELECT p.ID, p.post_title FROM ${PREFIX}posts p
LEFT JOIN ${PREFIX}postmeta pm ON p.ID=pm.post_id AND pm.meta_key='rank_math_title'
WHERE p.post_type='post' AND p.post_status='publish'
AND (pm.meta_value IS NULL OR pm.meta_value='');" --allow-root --path=$PATH
# Posts sem descricao SEO
wp db query "SELECT p.ID, p.post_title FROM ${PREFIX}posts p
LEFT JOIN ${PREFIX}postmeta pm ON p.ID=pm.post_id AND pm.meta_key='rank_math_description'
WHERE p.post_type='post' AND p.post_status='publish'
AND (pm.meta_value IS NULL OR pm.meta_value='');" --allow-root --path=$PATH
# Distribuicao de SEO scores
wp db query "SELECT
CASE WHEN CAST(meta_value AS UNSIGNED) >= 80 THEN 'Bom (80-100)'
WHEN CAST(meta_value AS UNSIGNED) >= 50 THEN 'OK (50-79)'
ELSE 'Fraco (0-49)' END AS faixa,
COUNT(*) AS total
FROM ${PREFIX}postmeta WHERE meta_key = 'rank_math_seo_score' GROUP BY faixa;" --allow-root --path=$PATH
# Top 404s (ultimos 30 dias)
wp db query "SELECT uri, SUM(times_accessed) as total FROM ${PREFIX}rank_math_404_logs
GROUP BY uri ORDER BY total DESC LIMIT 20;" --allow-root --path=$PATH
# Tamanho options (detectar bloat WooCommerce)
wp db query "SELECT option_name, LENGTH(option_value) as bytes FROM ${PREFIX}options
WHERE option_name LIKE 'rank%' AND autoload='yes' ORDER BY bytes DESC;" --allow-root --path=$PATH
# Listar TODAS as meta keys Rank Math existentes
wp db query "SELECT DISTINCT meta_key FROM ${PREFIX}postmeta WHERE meta_key LIKE 'rank_math%' ORDER BY meta_key;" --allow-root --path=$PATH
Passo 2 — estado modulos
wp option pluck rank_math_modules --allow-root --path=$PATH
wp option pluck rank-math-options-general strip_category_base --allow-root --path=$PATH
wp option pluck rank-math-options-titles title_separator --allow-root --path=$PATH
# Ver tabelas custom (usa % wildcard — funciona com qualquer prefixo)
wp db query "SHOW TABLES LIKE '%rank_math%';" --allow-root --path=$PATH
2. Actualizar meta SEO (/rank-math update-meta)
Meta key individual
# Titulo SEO
wp post meta update ID rank_math_title "%title% %sep% %sitename%" --allow-root --path=$PATH
# Descricao SEO (<160 chars)
wp post meta update ID rank_math_description "Texto conciso da pagina." --allow-root --path=$PATH
# Focus keyword
wp post meta update ID rank_math_focus_keyword "keyword1,keyword2" --allow-root --path=$PATH
# Robots (ARRAY JSON — obrigatorio --format=json)
wp post meta update ID rank_math_robots '["noindex"]' --format=json --allow-root --path=$PATH
# Advanced robots
wp post meta update ID rank_math_advanced_robots '{"max-snippet":"-1","max-video-preview":"-1","max-image-preview":"large"}' --format=json --allow-root --path=$PATH
# Canonical URL
wp post meta update ID rank_math_canonical_url "https://site.pt/url/" --allow-root --path=$PATH
# Pillar content
wp post meta update ID rank_math_pillar_content "on" --allow-root --path=$PATH
# Categoria primaria
wp post meta update ID rank_math_primary_category "15" --allow-root --path=$PATH
# Breadcrumb title
wp post meta update ID rank_math_breadcrumb_title "Titulo Breadcrumb" --allow-root --path=$PATH
# OpenGraph
wp post meta update ID rank_math_facebook_title "Titulo OG" --allow-root --path=$PATH
wp post meta update ID rank_math_facebook_description "Desc OG" --allow-root --path=$PATH
wp post meta update ID rank_math_facebook_image "https://site.pt/og.jpg" --allow-root --path=$PATH
wp post meta update ID rank_math_twitter_card_type "summary_large_image" --allow-root --path=$PATH
# Redirect per-post
wp post meta update ID rank_math_redirect_url_to "/nova-url/" --allow-root --path=$PATH
wp post meta update ID rank_math_redirection_header_code "301" --allow-root --path=$PATH
Bulk update (wp eval)
# Aplicar titulo padrao a todos os posts sem titulo
wp eval '
$posts = get_posts(["numberposts"=>-1,"post_status"=>"publish"]);
$updated = 0;
foreach ($posts as $p) {
if (!get_post_meta($p->ID, "rank_math_title", true)) {
update_post_meta($p->ID, "rank_math_title", "%title% %sep% %sitename%");
$updated++;
}
}
echo "$updated posts actualizados\n";
' --allow-root --path=$PATH
# Aplicar descricao a partir do excerpt
wp eval '
$posts = get_posts(["post_type"=>"post","numberposts"=>-1,"post_status"=>"publish"]);
$updated = 0;
foreach ($posts as $p) {
if (!get_post_meta($p->ID, "rank_math_description", true) && $p->post_excerpt) {
$desc = wp_trim_words($p->post_excerpt, 20, "...");
update_post_meta($p->ID, "rank_math_description", $desc);
$updated++;
}
}
echo "$updated posts actualizados\n";
' --allow-root --path=$PATH
Bulk via shell
# Actualizar titulo de todos os posts publicados
wp post list --post_type=post --post_status=publish --field=ID --allow-root --path=$PATH | while read id; do
wp post meta update $id rank_math_title "%title% %sep% %sitename%" --allow-root --path=$PATH
done
# Noindex em todos os drafts
wp post list --post_type=post --post_status=draft --field=ID --allow-root --path=$PATH | while read id; do
wp post meta update $id rank_math_robots '["noindex"]' --format=json --allow-root --path=$PATH
done
# Paralelo com xargs
wp post list --post_type=page --post_status=publish --field=ID --allow-root --path=$PATH | \
xargs -P4 -I {} wp post meta delete {} rank_math_canonical_url --allow-root --path=$PATH
Bulk via CSV
# Formato CSV: id,descricao
while IFS=, read -r post_id desc; do
wp post meta update "$post_id" rank_math_description "$desc" --allow-root --path=$PATH
done < descriptions.csv
3. Options globais (/rank-math options)
Regra critica: SEMPRE usar wp option patch, NUNCA wp option update em options serializadas.
# Separador de titulo
wp option patch update rank-math-options-titles title_separator "-" --allow-root --path=$PATH
# Templates por post type
wp option patch update rank-math-options-titles pt_post_title "%title% %sep% %sitename%" --allow-root --path=$PATH
wp option patch update rank-math-options-titles pt_page_title "%title% %sep% %sitename%" --allow-root --path=$PATH
wp option patch update rank-math-options-titles pt_product_title "%title% %sep% %currentyear% %sep% %sitename%" --allow-root --path=$PATH
# Homepage
wp option patch update rank-math-options-titles homepage_title "Titulo Site" --allow-root --path=$PATH
wp option patch update rank-math-options-titles homepage_description "Descricao Site" --allow-root --path=$PATH
# Remover base de categoria do URL
wp option patch update rank-math-options-general strip_category_base "on" --allow-root --path=$PATH
wp rewrite flush --allow-root --path=$PATH # OBRIGATORIO apos esta alteracao
# Breadcrumbs
wp option patch update rank-math-options-general breadcrumbs_separator ">" --allow-root --path=$PATH
# Nofollow links externos
wp option patch update rank-math-options-general nofollow_external_links "on" --allow-root --path=$PATH
# Knowledge Graph
wp option patch update rank-math-options-titles knowledgegraph_type "Organization" --allow-root --path=$PATH
wp option patch update rank-math-options-titles knowledgegraph_name "Descomplicar" --allow-root --path=$PATH
# Webmaster verification
wp option patch update rank-math-options-general google_verify "codigo" --allow-root --path=$PATH
# Verificar sub-key
wp option pluck rank-math-options-titles title_separator --allow-root --path=$PATH
# LER option completa (diagnostico)
wp option get rank-math-options-general --format=json --allow-root --path=$PATH
Gestao de modulos
# LER modulos activos
wp option get rank_math_modules --format=json --allow-root --path=$PATH
# ACTIVAR modulo (via wp eval — dispara hooks)
wp eval '
$modules = get_option("rank_math_modules", []);
if (!in_array("redirections", $modules)) {
$modules[] = "redirections";
update_option("rank_math_modules", $modules);
echo "Modulo activado.\n";
} else { echo "Ja activo.\n"; }
' --allow-root --path=$PATH
# DESACTIVAR modulo
wp eval '
$modules = get_option("rank_math_modules", []);
$modules = array_values(array_diff($modules, ["404-monitor"]));
update_option("rank_math_modules", $modules);
echo "Modulo desactivado.\n";
' --allow-root --path=$PATH
# Modulos disponiveis:
# sitemap, rich-snippet, redirections, 404-monitor, local-seo,
# woocommerce, image-seo, link-counter, instant-indexing, content-ai,
# analytics, role-manager, acf, amp, news-sitemap (PRO), video-sitemap (PRO)
4. Schema markup (/rank-math schema)
Schema armazenado como array PHP em rank_math_schema_{Type}. Usar wp eval (nao JSON directo).
Estrutura interna
{
"metadata": {"title": "Article", "type": "custom", "shortcode": "s-UNIQUE", "isPrimary": "1"},
"@type": "Article",
"headline": "%seo_title%",
"description": "%seo_description%"
}
type: "template"— herda globals |type: "custom"— personalizadoisPrimary: "1"— schema principal do post- Free: 1 schema/post | PRO: ilimitados
Criar schemas
# Article
wp eval '
update_post_meta(ID, "rank_math_schema_Article", [
"metadata" => ["title"=>"Article","type"=>"custom","shortcode"=>"s-".uniqid(),"isPrimary"=>"1"],
"@type"=>"Article",
"headline"=>"%seo_title%",
"description"=>"%seo_description%",
"keywords"=>"%keywords%",
"articleSection"=>"%categories%",
"image"=>["@type"=>"ImageObject","url"=>"%post_thumbnail%"],
"author"=>["@type"=>"Person","name"=>"%name%"],
"publisher"=>["@type"=>"Organization","name"=>"%sitename%","logo"=>""],
"datePublished"=>"%date(Y-m-dTH:i:sP)%",
"dateModified"=>"%modified(Y-m-dTH:i:sP)%"
]);
echo "Schema Article criado\n";
' --user=1 --allow-root --path=$PATH
# FAQ
wp eval '
update_post_meta(ID, "rank_math_schema_FAQPage", [
"metadata" => ["title"=>"FAQ","type"=>"custom","shortcode"=>"s-".uniqid(),"isPrimary"=>"0"],
"@type"=>"FAQPage",
"mainEntity"=>[
["@type"=>"Question","name"=>"Pergunta 1","acceptedAnswer"=>["@type"=>"Answer","text"=>"Resposta 1"]],
["@type"=>"Question","name"=>"Pergunta 2","acceptedAnswer"=>["@type"=>"Answer","text"=>"Resposta 2"]]
]
]);
echo "Schema FAQ criado\n";
' --user=1 --allow-root --path=$PATH
# Product (WooCommerce)
wp eval '
update_post_meta(ID, "rank_math_schema_Product", [
"metadata" => ["title"=>"Product","type"=>"custom","shortcode"=>"s-".uniqid(),"isPrimary"=>"1"],
"@type"=>"Product",
"name"=>"%title%",
"description"=>"%excerpt%",
"sku"=>"SKU-001",
"brand"=>["@type"=>"Brand","name"=>"Marca"],
"image"=>["@type"=>"ImageObject","url"=>"%post_thumbnail%"],
"offers"=>[
"@type"=>"Offer","price"=>"29.99","priceCurrency"=>"EUR",
"availability"=>"https://schema.org/InStock","url"=>"%url%",
"priceValidUntil"=>"2026-12-31"
]
]);
echo "Schema Product criado\n";
' --user=1 --allow-root --path=$PATH
# LocalBusiness
wp eval '
update_post_meta(ID, "rank_math_schema_LocalBusiness", [
"metadata" => ["title"=>"LocalBusiness","type"=>"custom","shortcode"=>"s-".uniqid(),"isPrimary"=>"1"],
"@type"=>"LocalBusiness",
"name"=>"Nome Empresa",
"description"=>"%seo_description%",
"url"=>"%url%",
"email"=>"email@empresa.pt",
"telephone"=>"+351 XXX XXX XXX",
"address"=>["@type"=>"PostalAddress","streetAddress"=>"Rua X","addressLocality"=>"Cidade","postalCode"=>"XXXX-XXX","addressCountry"=>"PT"],
"geo"=>["@type"=>"GeoCoordinates","latitude"=>"38.7","longitude"=>"-9.1"],
"openingHoursSpecification"=>[
["@type"=>"OpeningHoursSpecification","dayOfWeek"=>["Monday","Tuesday","Wednesday","Thursday","Friday"],"opens"=>"09:00","closes"=>"18:00"]
],
"image"=>"%post_thumbnail%"
]);
echo "Schema LocalBusiness criado\n";
' --user=1 --allow-root --path=$PATH
# VideoObject
wp eval '
update_post_meta(ID, "rank_math_schema_VideoObject", [
"metadata" => ["title"=>"VideoObject","type"=>"custom","shortcode"=>"s-".uniqid(),"isPrimary"=>"0"],
"@type"=>"VideoObject",
"name"=>"%seo_title%",
"description"=>"%seo_description%",
"thumbnailUrl"=>"%post_thumbnail%",
"uploadDate"=>"%date(Y-m-dTH:i:sP)%",
"contentUrl"=>"https://exemplo.pt/video.mp4",
"embedUrl"=>"https://youtube.com/embed/VIDEO_ID"
]);
echo "Schema VideoObject criado\n";
' --user=1 --allow-root --path=$PATH
Actualizar/apagar schema
# Actualizar campo especifico
wp eval '
$schema = get_post_meta(ID, "rank_math_schema_Article", true);
if ($schema) {
$schema["headline"] = "Novo Titulo";
update_post_meta(ID, "rank_math_schema_Article", $schema);
echo "Actualizado.\n";
}
' --allow-root --path=$PATH
# Apagar schema corrompido
wp post meta delete ID rank_math_schema_Article --allow-root --path=$PATH
# Apagar TODOS os schemas de um post
wp eval '
global $wpdb;
$wpdb->query($wpdb->prepare(
"DELETE FROM {$wpdb->postmeta} WHERE post_id = %d AND meta_key LIKE %s",
ID, "rank_math_schema_%"
));
echo "Todos os schemas eliminados.\n";
' --allow-root --path=$PATH
5. Redirects (/rank-math redirects)
CRUD via API PHP (recomendado)
# Criar redirect 301
wp eval '
\RankMath\Redirections\DB::add([
"id"=>"",
"sources"=>[["pattern"=>"/url-antiga/","comparison"=>"exact"]],
"url_to"=>"/url-nova/",
"header_code"=>301,
"status"=>"active",
]);
echo "Redirect criado\n";
' --allow-root --path=$PATH
# Redirect regex
wp eval '
\RankMath\Redirections\DB::add([
"id"=>"",
"sources"=>[["pattern"=>"^/blog/2023/.*$","comparison"=>"regex"]],
"url_to"=>"/blog/",
"header_code"=>301,
"status"=>"active",
]);
' --allow-root --path=$PATH
# Redirect 410 (conteudo removido)
wp eval '
\RankMath\Redirections\DB::add([
"id"=>"",
"sources"=>[["pattern"=>"/removida/","comparison"=>"exact"]],
"url_to"=>"",
"header_code"=>410,
"status"=>"active",
]);
' --allow-root --path=$PATH
# Actualizar
wp eval '
\RankMath\Redirections\DB::update([
"id"=>42,
"sources"=>[["pattern"=>"/url-antiga/","comparison"=>"exact"]],
"url_to"=>"/url-nova/",
"header_code"=>301,
"status"=>"active",
]);
echo "Actualizado\n";
' --allow-root --path=$PATH
# Apagar
wp eval '\RankMath\Redirections\DB::delete(42); echo "Eliminado\n";' --allow-root --path=$PATH
wp eval '\RankMath\Redirections\DB::delete([42, 43, 44]); echo "Eliminados\n";' --allow-root --path=$PATH
# Bulk criar
wp eval '
$redirects = [
["/antiga-1/", "/nova-1/", 301],
["/antiga-2/", "/nova-2/", 301],
["/removida/", "", 410],
];
foreach ($redirects as $r) {
$id = \RankMath\Redirections\DB::add([
"id"=>"", "sources"=>[["pattern"=>$r[0],"comparison"=>"exact"]],
"url_to"=>$r[1], "header_code"=>$r[2], "status"=>"active",
]);
echo "#{$id}: {$r[0]} -> {$r[1]} ({$r[2]})\n";
}
' --allow-root --path=$PATH
# Validar
curl -I -s https://site.pt/url-antiga/ | grep HTTP
Tipos de comparacao
| comparison | Comportamento |
|---|---|
exact |
Match exacto |
contains |
URL contem pattern |
start |
URL comeca com pattern |
end |
URL termina com pattern |
regex |
Expressao regular |
404 Monitor
# Top 404s
wp db query "SELECT uri, SUM(times_accessed) as total FROM ${PREFIX}rank_math_404_logs
GROUP BY uri ORDER BY total DESC LIMIT 20;" --allow-root --path=$PATH
# Limpar logs antigos (>30 dias)
wp db query "DELETE FROM ${PREFIX}rank_math_404_logs WHERE accessed < DATE_SUB(NOW(), INTERVAL 30 DAY);" --allow-root --path=$PATH
# Truncar tudo
wp db query "TRUNCATE TABLE ${PREFIX}rank_math_404_logs;" --allow-root --path=$PATH
6. Sitemap (/rank-math sitemap)
# Regenerar sitemap
wp rankmath sitemap generate --allow-root --path=$PATH
# Invalidar cache de sitemap via API PHP
wp eval '\RankMath\Sitemap\Cache::invalidate_storage(); echo "Cache invalidada.\n";' --allow-root --path=$PATH
# Invalidar sitemap de tipo especifico
wp eval '\RankMath\Sitemap\Cache::invalidate_storage("post"); echo "Sitemap posts invalidado.\n";' --allow-root --path=$PATH
# Incluir/excluir post-types
wp option patch update rank-math-options-sitemap pt_post_sitemap "on" --allow-root --path=$PATH
wp option patch update rank-math-options-sitemap pt_attachment_sitemap "off" --allow-root --path=$PATH
# Excluir posts especificos
wp eval '
$opts = get_option("rank-math-options-sitemap");
$opts["exclude_posts"] = "123,456,789";
update_option("rank-math-options-sitemap", $opts);
' --allow-root --path=$PATH
# Itens por pagina (reduzir em sites grandes)
wp option patch update rank-math-options-sitemap items_per_page "200" --allow-root --path=$PATH
# Verificar setting
wp option pluck rank-math-options-sitemap pt_post_sitemap --allow-root --path=$PATH
Nginx rewrite rules (obrigatorio em Nginx puro):
rewrite ^/sitemap_index.xml$ /index.php?sitemap=1 last;
rewrite ^/([^/]+?)-sitemap([0-9]+)?.xml$ /index.php?sitemap=$1&sitemap_n=$2 last;
rewrite ^/([a-z]+)?-sitemap\.xsl$ /index.php?xsl=$1 last;
7. Instant Indexing (/rank-math indexing) — PRO
IndexNow (integrado no Rank Math)
# Submeter URL individual
wp eval '
$url = "https://site.pt/novo-artigo/";
$api_key = get_option("rank-math-options-instant-indexing")["indexnow_api_key"] ?? "";
$response = wp_remote_post("https://api.indexnow.org/indexnow", [
"headers" => ["Content-Type" => "application/json"],
"body" => json_encode([
"host" => parse_url(home_url(), PHP_URL_HOST),
"key" => $api_key,
"urlList" => [$url],
]),
]);
echo "Codigo: " . wp_remote_retrieve_response_code($response) . "\n";
' --allow-root --path=$PATH
# Submeter URLs em bulk
wp eval '
$urls = ["https://site.pt/post-1/", "https://site.pt/post-2/", "https://site.pt/post-3/"];
$api_key = get_option("rank-math-options-instant-indexing")["indexnow_api_key"] ?? "";
$response = wp_remote_post("https://api.indexnow.org/indexnow", [
"headers" => ["Content-Type" => "application/json"],
"body" => json_encode([
"host" => parse_url(home_url(), PHP_URL_HOST),
"key" => $api_key,
"urlList" => $urls,
]),
]);
echo "Codigo: " . wp_remote_retrieve_response_code($response) . "\n";
' --allow-root --path=$PATH
# Submeter todos os posts publicados nos ultimos 7 dias
wp eval '
$posts = get_posts(["numberposts"=>-1,"post_status"=>"publish","date_query"=>[["after"=>"7 days ago"]]]);
$urls = array_map(function($p) { return get_permalink($p->ID); }, $posts);
$api_key = get_option("rank-math-options-instant-indexing")["indexnow_api_key"] ?? "";
$chunks = array_chunk($urls, 10000); // IndexNow max 10k por pedido
foreach ($chunks as $chunk) {
$response = wp_remote_post("https://api.indexnow.org/indexnow", [
"headers" => ["Content-Type" => "application/json"],
"body" => json_encode([
"host" => parse_url(home_url(), PHP_URL_HOST),
"key" => $api_key,
"urlList" => $chunk,
]),
]);
echo count($chunk) . " URLs submetidos. Codigo: " . wp_remote_retrieve_response_code($response) . "\n";
}
' --allow-root --path=$PATH
# Verificar API key
wp eval 'echo get_option("rank-math-options-instant-indexing")["indexnow_api_key"] ?? "nao definida"; echo "\n";' --allow-root --path=$PATH
# Configurar post types para IndexNow
wp option patch update rank-math-options-instant-indexing bing_post_types '["post","page","product"]' --format=json --allow-root --path=$PATH
Codigos resposta IndexNow: 200=sucesso, 202=aceite (pendente), 400=invalido, 403=key invalida, 429=rate limit.
Google Indexing API (via classes RM PRO)
# Submeter URL via API interna RM
wp eval '
$target = get_permalink(99);
\RankMath\Instant_Indexing\Api::submit($target, "URL_UPDATED");
echo "Submetido: $target\n";
' --allow-root --path=$PATH
Limites: Google Indexing API quota ~200 pedidos/dia. Nao submeter URLs voláteis (parametrizados, facturacao).
8. Analytics PRO (/rank-math analytics)
Tabelas de analytics (apenas com modulo analytics activo + PRO)
# Dados Google Search Console armazenados
wp db query "SELECT page, SUM(clicks) as clicks, SUM(impressions) as impressions,
AVG(position) as avg_pos, AVG(ctr) as avg_ctr
FROM ${PREFIX}rank_math_analytics_gsc
WHERE created >= DATE_SUB(NOW(), INTERVAL 30 DAY)
GROUP BY page ORDER BY clicks DESC LIMIT 20;" --allow-root --path=$PATH
# Top queries
wp db query "SELECT query, SUM(clicks) as clicks, SUM(impressions) as impressions,
AVG(position) as avg_pos
FROM ${PREFIX}rank_math_analytics_gsc
WHERE created >= DATE_SUB(NOW(), INTERVAL 30 DAY)
GROUP BY query ORDER BY clicks DESC LIMIT 30;" --allow-root --path=$PATH
# Objectos rastreados (seo score, indexabilidade)
wp db query "SELECT page, seo_score, is_indexable, object_type
FROM ${PREFIX}rank_math_analytics_objects
ORDER BY seo_score ASC LIMIT 20;" --allow-root --path=$PATH
# Posts com pior ranking
wp db query "SELECT gsc.page, gsc.query, AVG(gsc.position) as avg_pos, ao.seo_score
FROM ${PREFIX}rank_math_analytics_gsc gsc
LEFT JOIN ${PREFIX}rank_math_analytics_objects ao ON gsc.page = ao.page
WHERE gsc.created >= DATE_SUB(NOW(), INTERVAL 7 DAY)
GROUP BY gsc.page, gsc.query
HAVING avg_pos > 10
ORDER BY gsc.impressions DESC LIMIT 20;" --allow-root --path=$PATH
# Google Analytics pageviews (se integrado)
wp db query "SELECT page, SUM(pageviews) as views, SUM(visitors) as visitors
FROM ${PREFIX}rank_math_analytics_ga
GROUP BY page ORDER BY views DESC LIMIT 20;" --allow-root --path=$PATH
# Links internos
wp db query "SELECT post_id, internal_link_count, external_link_count, incoming_link_count
FROM ${PREFIX}rank_math_internal_meta
ORDER BY incoming_link_count ASC LIMIT 20;" --allow-root --path=$PATH
9. Taxonomias e WooCommerce (/rank-math taxonomy)
Terms (categorias, tags, taxonomias custom)
# LER titulo SEO de categoria
wp term meta get 15 rank_math_title --allow-root --path=$PATH
# DEFINIR description SEO
wp term meta update 23 rank_math_description "Descricao SEO da tag." --allow-root --path=$PATH
# DEFINIR noindex numa taxonomia
wp term meta update 23 rank_math_robots '["noindex"]' --format=json --allow-root --path=$PATH
# CUIDADO: noindex numa categoria remove do indice TODAS as paginas arquivo dessa cat
WooCommerce bulk
# Titulo SEO para todas as categorias de produto sem titulo
wp eval '
$terms = get_terms(["taxonomy"=>"product_cat","hide_empty"=>false]);
$updated = 0;
foreach ($terms as $t) {
if (!get_term_meta($t->term_id, "rank_math_title", true)) {
update_term_meta($t->term_id, "rank_math_title", "%term% %sep% %sitename%");
$updated++;
}
}
echo "$updated categorias actualizadas\n";
' --allow-root --path=$PATH
# Descricao SEO para categorias de produto a partir da descricao da categoria
wp eval '
$terms = get_terms(["taxonomy"=>"product_cat","hide_empty"=>false]);
$updated = 0;
foreach ($terms as $t) {
if (!get_term_meta($t->term_id, "rank_math_description", true) && $t->description) {
$desc = wp_trim_words($t->description, 25, "...");
update_term_meta($t->term_id, "rank_math_description", $desc);
$updated++;
}
}
echo "$updated categorias actualizadas\n";
' --allow-root --path=$PATH
# Noindex em taxonomias de atributos vazias (cor, tamanho, etc.)
wp eval '
$taxonomies = wc_get_attribute_taxonomy_names();
$noindexed = 0;
foreach ($taxonomies as $tax) {
$terms = get_terms(["taxonomy"=>$tax,"hide_empty"=>true]);
foreach ($terms as $t) {
if (!get_term_meta($t->term_id, "rank_math_robots", true)) {
update_term_meta($t->term_id, "rank_math_robots", ["noindex"]);
$noindexed++;
}
}
}
echo "$noindexed atributos noindexados\n";
' --allow-root --path=$PATH
User meta (arquivo de autor)
wp user meta update 1 rank_math_title "Nome Autor — Especialista WordPress" --allow-root --path=$PATH
wp user meta update 1 rank_math_description "Artigos sobre WordPress e SEO." --allow-root --path=$PATH
10. News Sitemap PRO (/rank-math news)
# Activar modulo
wp eval '
$modules = get_option("rank_math_modules", []);
if (!in_array("news-sitemap", $modules)) { $modules[] = "news-sitemap"; update_option("rank_math_modules", $modules); }
echo "News Sitemap activo\n";
' --allow-root --path=$PATH
# Definir meta por post
wp post meta update ID rank_math_news_sitemap_robots "index" --allow-root --path=$PATH
wp post meta update ID rank_math_news_sitemap_genres "PressRelease" --allow-root --path=$PATH
# Generos: Blog, PressRelease, Satire, OpEd
wp post meta update ID rank_math_news_sitemap_keywords "ia,automacao,marketing" --allow-root --path=$PATH
wp post meta update ID rank_math_news_sitemap_stock_tickers "GOOG,MSFT" --allow-root --path=$PATH
# Configurar post types para news sitemap
wp eval '
$opts = get_option("rank-math-options-sitemap");
$opts["news_sitemap_post_type"] = ["post"];
update_option("rank-math-options-sitemap", $opts);
' --allow-root --path=$PATH
11. Hooks e filtros (/rank-math hooks)
Frontend
# Modificar titulo via filtro (persistente via rank-math.php)
wp eval '
file_put_contents(get_stylesheet_directory() . "/rank-math.php",
"<?php\n// Filtros custom Rank Math\n" .
"add_filter(\"rank_math/frontend/show_keywords\", \"__return_true\");\n"
);
echo "Filtro adicionado.\n";
' --allow-root --path=$PATH
Hooks uteis (para rank-math.php ou mu-plugin)
// rank_math/frontend/robots — modificar robots programaticamente
add_filter('rank_math/frontend/robots', function($robots) {
if (is_tax('product_cat')) { $robots['noindex'] = 'noindex'; }
return $robots;
});
// rank_math/json_ld — modificar todo o output JSON-LD
add_filter('rank_math/json_ld', function($data, $jsonld) { return $data; }, 10, 2);
// rank_math/snippet/rich_snippet_article_entity — modificar schema Article
add_filter('rank_math/snippet/rich_snippet_article_entity', function($entity) {
$entity['headline'] = 'Titulo Custom';
return $entity;
});
// rank_math/sitemap/enable_caching — desactivar cache sitemap
add_filter('rank_math/sitemap/enable_caching', '__return_false');
// rank_math/focus_keyword/maxtags — alterar limite keywords (Free: 5)
add_filter('rank_math/focus_keyword/maxtags', function() { return 10; });
// rank_math/metabox/priority — baixar prioridade do metabox
add_filter('rank_math/metabox/priority', function() { return 'low'; });
// rank_math/sitemap/remove_credit
add_filter('rank_math/sitemap/remove_credit', '__return_true');
Ficheiro auto-incluido: O Rank Math carrega automaticamente /wp-content/themes/{tema-activo}/rank-math.php quando o plugin esta activo. Colocar filtros persistentes aqui.
12. Backup e rollback (/rank-math backup)
Backup antes de operacoes em massa
# Exportar options Rank Math
wp eval '
$options = ["rank-math-options-general","rank-math-options-titles","rank-math-options-sitemap","rank_math_modules","rank-math-options-instant-indexing"];
$backup = [];
foreach ($options as $opt) { $backup[$opt] = get_option($opt); }
file_put_contents("/tmp/rankmath-options-backup.json", json_encode($backup, JSON_PRETTY_PRINT));
echo "Options exportadas para /tmp/rankmath-options-backup.json\n";
' --allow-root --path=$PATH
# Exportar todos os post meta Rank Math
wp eval '
global $wpdb;
$results = $wpdb->get_results("SELECT post_id, meta_key, meta_value FROM {$wpdb->postmeta} WHERE meta_key LIKE \"rank_math_%\"", ARRAY_A);
file_put_contents("/tmp/rankmath-postmeta-backup.json", json_encode($results));
echo count($results) . " meta entries exportadas\n";
' --allow-root --path=$PATH
# Exportar redirects
wp db query "SELECT * FROM ${PREFIX}rank_math_redirections;" --allow-root --path=$PATH > /tmp/rankmath-redirections-backup.tsv
# Exportar dados SEO para CSV
wp eval '
$posts = get_posts(["post_type"=>"post","post_status"=>"publish","numberposts"=>-1]);
$fp = fopen("/tmp/rankmath-seo-export.csv", "w");
fputcsv($fp, ["ID","Titulo","SEO_Title","Description","Focus_KW","Score","Canonical"]);
foreach ($posts as $p) {
fputcsv($fp, [
$p->ID, $p->post_title,
get_post_meta($p->ID, "rank_math_title", true),
get_post_meta($p->ID, "rank_math_description", true),
get_post_meta($p->ID, "rank_math_focus_keyword", true),
get_post_meta($p->ID, "rank_math_seo_score", true),
get_post_meta($p->ID, "rank_math_canonical_url", true),
]);
}
fclose($fp);
echo count($posts) . " posts exportados\n";
' --allow-root --path=$PATH
Rollback
# Restaurar options de backup
wp eval '
$backup = json_decode(file_get_contents("/tmp/rankmath-options-backup.json"), true);
foreach ($backup as $key => $value) {
update_option($key, $value);
echo "Restaurado: $key\n";
}
' --allow-root --path=$PATH
# Restaurar post meta de backup
wp eval '
$entries = json_decode(file_get_contents("/tmp/rankmath-postmeta-backup.json"), true);
$restored = 0;
foreach ($entries as $e) {
update_post_meta($e["post_id"], $e["meta_key"], maybe_unserialize($e["meta_value"]));
$restored++;
}
echo "$restored meta entries restauradas\n";
' --allow-root --path=$PATH
13. Provisioning (/rank-math provision)
Configuracao completa de um site novo.
# 1. Activar modulos essenciais
wp eval '
update_option("rank_math_modules", ["sitemap","rich-snippet","redirections","404-monitor","seo-analysis","link-counter","instant-indexing","image-seo"]);
echo "Modulos configurados\n";
' --allow-root --path=$PATH
# 2. Configuracoes globais
wp option patch update rank-math-options-titles title_separator "-" --allow-root --path=$PATH
wp option patch update rank-math-options-titles knowledgegraph_type "Organization" --allow-root --path=$PATH
wp option patch update rank-math-options-titles knowledgegraph_name "Nome Empresa" --allow-root --path=$PATH
wp option patch update rank-math-options-general strip_category_base "on" --allow-root --path=$PATH
wp option patch update rank-math-options-general nofollow_external_links "on" --allow-root --path=$PATH
wp option patch update rank-math-options-general attachment_redirect_urls "on" --allow-root --path=$PATH
wp option patch update rank-math-options-sitemap pt_attachment_sitemap "off" --allow-root --path=$PATH
# 3. Templates por post type
wp option patch update rank-math-options-titles pt_post_title "%title% %sep% %sitename%" --allow-root --path=$PATH
wp option patch update rank-math-options-titles pt_page_title "%title% %sep% %sitename%" --allow-root --path=$PATH
wp option patch update rank-math-options-titles pt_post_description "%excerpt%" --allow-root --path=$PATH
# 4. Flush e regenerar
wp rewrite flush --allow-root --path=$PATH
wp rankmath sitemap generate --allow-root --path=$PATH
echo "Provisioning concluido"
14. Validacao pos-aplicacao
Verificar schema no HTML
# Verificar JSON-LD no frontend
curl -s "https://site.pt/post/" | grep -o '"@type":"[^"]*"' | sort -u
# Extrair JSON-LD completo
curl -s "https://site.pt/post/" | grep -oP '<script type="application/ld\+json">\K[^<]+'
# Verificar meta robots
curl -s "https://site.pt/post/" | grep -i 'meta name="robots"'
# Verificar OG tags
curl -s "https://site.pt/post/" | grep -i 'property="og:'
# Verificar canonical
curl -s "https://site.pt/post/" | grep -i 'rel="canonical"'
Confirmar meta na BD
wp post meta list ID --format=table --allow-root --path=$PATH | grep rank_math
wp post meta get ID rank_math_robots --format=json --allow-root --path=$PATH
15. Módulos — referência completa (Free vs PRO)
Lista verificada ao vivo em descomplicar.pt (Rank Math Pro activo, licença "full services") via wp option get rank_math_modules --format=json e confirmada contra o filesystem (includes/modules/ de seo-by-rank-math e seo-by-rank-math-pro), 16-08-2026.
# Ver modulos activos (array INDEXADO de slugs — NAO um map slug=>bool)
wp option get rank_math_modules --format=json --allow-root --path=$PATH
# Activar um modulo (wp eval — NUNCA wp option patch update aqui, a option e um array sequencial)
wp eval '
$modules = get_option("rank_math_modules", []);
if (!in_array("SLUG", $modules)) { $modules[] = "SLUG"; update_option("rank_math_modules", $modules); }
' --allow-root --path=$PATH
# Desactivar um modulo
wp eval '
$modules = get_option("rank_math_modules", []);
$modules = array_values(array_diff($modules, ["SLUG"]));
update_option("rank_math_modules", $modules);
' --allow-root --path=$PATH
| Slug | Nome | Disponibilidade | Nota |
|---|---|---|---|
seo-analysis |
SEO Analysis | Free | Score SEO no editor |
link-counter (dir links) |
Link Counter | Free | Contagem links internos/externos |
sitemap |
XML Sitemap | Free | — |
rich-snippet (dir schema) |
Schema/Rich Snippets | Free | 1 schema/pagina; PRO liberta multiplos + Schema Builder custom |
redirections |
Redirections | Free (Advanced Mode) | — |
404-monitor |
404 Monitor | Free (opcao basica) / PRO (modulo dedicado) | Free: so 404_monitor_mode em General, sem tabela propria. PRO: modulo com tabela wp_rank_math_404_logs |
instant-indexing |
Instant Indexing (IndexNow) | Free | Google Indexing API adicional (via classes RM) e PRO |
woocommerce |
WooCommerce SEO | Free | Requer plugin WooCommerce activo |
acf |
ACF Integration | Free | Requer plugin ACF activo |
analytics |
Analytics | Free (basico) / PRO (avancado) | GSC/GA; historico alargado e PRO |
role-manager |
Role Manager | Free | — |
buddypress |
BuddyPress Integration | Free | Requer plugin BuddyPress |
bbpress (dir bbPress) |
bbPress Integration | Free | Requer plugin bbPress |
web-stories |
Web Stories SEO | Free | Requer plugin Web Stories |
ai-visibility |
AI Visibility | Free | Achado 16-08-2026 — modulo novo, monitoriza citacoes em AI Overviews/LLMs |
content-ai |
Content AI | Free (limitado, requer conta ligada) / PRO (ilimitado) | Confirmado activo em emanuelalmeida.pt mesmo antes do Pro — depende da conta ligada, nao do plugin Pro |
image-seo |
Image SEO | PRO exclusivo | Alt/title automatico em imagens |
local-seo |
Local SEO | PRO exclusivo | Schema LocalBusiness multi-localizacao |
llms-txt (dir llms) |
LLMs.txt | PRO exclusivo | Gera /llms.txt automaticamente — ver achado de sessao em §16.2 |
news-sitemap |
News Sitemap | PRO exclusivo | — |
video-sitemap |
Video Sitemap | PRO exclusivo | Confirmado no filesystem (includes/modules/video-sitemap), nao estava activo no site verificado |
marketplace |
Marketplace (addons) | PRO exclusivo | — |
link-genius |
Link Genius | PRO exclusivo | So existe no filesystem Pro; sem equivalente Free |
podcast |
Podcast SEO | PRO exclusivo | So existe no filesystem Pro |
Nota sobre image-seo e local-seo: existe a pasta do modulo em AMBOS os plugins (seo-by-rank-math/includes/modules/image-seo e local-seo), mas o registo efectivo do modulo como disponivel para activacao depende da licenca PRO ligada — confirmado ao vivo: so aparecem em rank_math_modules em sites com Pro activo e licenciado.
Sequencia de cache (sempre apos alteracoes)
wp cache flush --allow-root --path=$PATH
wp transient delete --all --allow-root --path=$PATH
wp rewrite flush --allow-root --path=$PATH
wp rankmath sitemap generate --allow-root --path=$PATH
# Limpar page cache (adaptar ao plugin):
# wp wp-rocket clean --confirm # WP Rocket
# wp litespeed-purge all # LiteSpeed
Alteracoes via
wp db querynao invalidam Redis/Memcached. Sempre executarwp cache flush.
Variaveis dinamicas
Post: %title% %excerpt% %seo_title% %seo_description% %url% %post_thumbnail% %id% %focuskw% %keywords%
Data: %date(Y-m-d)% %modified(Y-m-d)% %currentyear% %currentmonth%
Taxonomia: %category% %categories% %tag% %tags% %term% %term_description% %customterm(taxonomy)%
Site: %sep% %sitename% %sitedesc% %org_name% %org_logo% %org_url%
Autor: %name% %userid% %user_description%
Avancado: %customfield(field-name)% %search_query% %page% %pagenumber%
WooCommerce: %wc_price% %wc_sku% %wc_shortdesc% %wc_brand%
PRO: %randomword(a|b|c)% %imagealt% %imagetitle%
Gotchas criticos
| Problema | Causa | Solucao |
|---|---|---|
| Robots nao aplicam | String em vez de array | '["noindex"]' --format=json |
| Options corrompidas | wp option update em serializada |
Sempre wp option patch |
| Alteracao nao visivel | Object cache (Redis) | wp cache flush |
| Schema quebra editor | JSON invalido em schema_* | wp post meta delete ID rank_math_schema_* |
| Sitemap 404 no Nginx | Faltam rewrite rules | Adicionar regras ao server block |
| SEO score nao actualiza | Calculado no Gutenberg | Apagar rank_math_seo_score para recalcular |
| Bloat WooCommerce | options-titles por atributo | Redis + reduzir atributos |
| Titulo ignorado | Cache de pagina | Limpar plugin de cache |
| Permissoes bloqueiam | Sem contexto user | --user=1 em todos os wp eval |
| Double serialization | wp option update com JSON | Usar wp option patch ou wp eval |
| Serialization corrupta | Search-replace directo | Usar wp search-replace (serialization-aware) |
| wp option patch sem hooks | patch nao dispara hooks | wp eval com update_option() para side-effects |
Capabilities Rank Math
rank_math_general rank_math_sitemap rank_math_404_monitor rank_math_redirections rank_math_role_manager rank_math_analytics rank_math_onpage_general rank_math_onpage_advanced rank_math_onpage_snippet rank_math_onpage_social rank_math_content_ai
Free vs PRO — funcionalidades WP-CLI
| Funcionalidade | Free | PRO |
|---|---|---|
wp rankmath sitemap generate |
sim | sim |
| Meta por post/term/user | sim | sim |
| Options globais | sim | sim |
| Schema markup (1/post) | sim | sim |
| Schemas multiplos/post | nao | sim |
| Custom Schema Builder (840+ tipos) | nao | sim |
| Redirections | sim | sim |
| 404 Monitor (opção básica) | sim | sim |
| 404 Monitor (módulo dedicado, tabela própria — ver §15) | nao | sim |
| Instant Indexing (IndexNow) | sim | sim |
| Google Indexing API | nao | sim |
| Analytics GSC/GA | basico | avancado |
| News Sitemap | nao | sim |
| Video Sitemap | nao | sim |
| Content AI | limitado | sim |
| CSV import/export SEO | nao | sim |
| Focus keywords ilimitadas | 5 max | ilimitado |
Migracao Yoast -> Rank Math
# BACKUP OBRIGATORIO
wp db export backup-pre-migracao-$(date +%Y%m%d).sql --allow-root --path=$PATH
# Detectar prefixo
PREFIX=$(wp db prefix --allow-root --path=$PATH)
# Migrar titulo SEO
wp db query "INSERT INTO ${PREFIX}postmeta (post_id, meta_key, meta_value)
SELECT post_id, 'rank_math_title', meta_value FROM ${PREFIX}postmeta
WHERE meta_key = '_yoast_wpseo_title' AND meta_value != ''
AND post_id NOT IN (SELECT post_id FROM ${PREFIX}postmeta WHERE meta_key = 'rank_math_title');" --allow-root --path=$PATH
# Migrar meta description
wp db query "INSERT INTO ${PREFIX}postmeta (post_id, meta_key, meta_value)
SELECT post_id, 'rank_math_description', meta_value FROM ${PREFIX}postmeta
WHERE meta_key = '_yoast_wpseo_metadesc' AND meta_value != ''
AND post_id NOT IN (SELECT post_id FROM ${PREFIX}postmeta WHERE meta_key = 'rank_math_description');" --allow-root --path=$PATH
# Migrar focus keyword
wp db query "INSERT INTO ${PREFIX}postmeta (post_id, meta_key, meta_value)
SELECT post_id, 'rank_math_focus_keyword', meta_value FROM ${PREFIX}postmeta
WHERE meta_key = '_yoast_wpseo_focuskw' AND meta_value != ''
AND post_id NOT IN (SELECT post_id FROM ${PREFIX}postmeta WHERE meta_key = 'rank_math_focus_keyword');" --allow-root --path=$PATH
# Sempre seguido de:
wp cache flush --allow-root --path=$PATH
16. Achados de sessão — bundle Descomplicar (16-08-2026)
Achados da auditoria de seguranca/infra ao bundle de 7 sites Descomplicar (CONFIG-Plugins-Referencia.md §7, BUNDLE-Excelencia-WP.md). Licenca Rank Math confirmada pelo utilizador como "full services" — cobre os 7 sites, nao e por assento individual.
16.1 Distribuicao real do Pro nos 7 sites
| Site | seo-by-rank-math-pro instalado |
Licenca ligada (rank_math_connect_data.connected) |
Estado |
|---|---|---|---|
descomplicar.pt |
sim | sim | Pro operacional |
carstuff.pt |
sim | sim | Pro operacional |
emanuelalmeida.pt |
sim | sim | Pro operacional |
familyclinic.pt |
sim | sim | Pro operacional |
ignitionvortex.pt |
sim | nao | Plugin instalado, licenca por ligar |
solarfvengenharia.com |
sim | nao | Plugin instalado, licenca por ligar |
watercontrol.pt |
sim | nao | Plugin instalado, licenca por ligar |
A ligacao de conta faz-se por OAuth no wp-admin (Rank Math → Ligar a sua conta). Nao simular via wp-cli copiando rank_math_connect_data de outro dominio — a API do Rank Math valida site_url no lado do servidor; copiar o valor arrisca invalidar ou confundir a licenca de origem.
# Verificar ligacao de conta num site
wp option get rank_math_connect_data --format=json --allow-root --path=$PATH
16.2 llms-txt como causa raiz de /llms.txt em falta
/llms.txt esteve em falta em emanuelalmeida.pt (desde 12-08-2026 pelo menos) apesar da conta Rank Math ja estar ligada. Causa raiz: o modulo llms-txt (gera /llms.txt automaticamente) e exclusivo Pro — o site so tinha seo-by-rank-math (free) instalado, sem seo-by-rank-math-pro. Corrigido 16-08-2026: instalado o plugin Pro + activado o modulo llms-txt (nao vem activo por omissao mesmo com Pro) + verificado /llms.txt → HTTP 200 ao vivo, em emanuelalmeida.pt e familyclinic.pt.
# Diagnosticar /llms.txt em falta
wp option get rank_math_modules --format=json --allow-root --path=$PATH | grep -q llms-txt && echo "modulo activo" || echo "modulo AUSENTE — instalar Pro + activar"
# Activar o modulo depois do Pro estar instalado e licenciado
wp eval '
$modules = get_option("rank_math_modules", []);
if (!in_array("llms-txt", $modules)) { $modules[] = "llms-txt"; update_option("rank_math_modules", $modules); }
' --allow-root --path=$PATH
# Verificar ao vivo
curl -sI "https://SITE.pt/llms.txt" | head -1
16.3 Licencas — usar /full-cliente, nao duplicar aqui
A gestao de licenca/ligacao de conta Rank Math Pro faz parte do broker de licencas FULL.Cliente (api.full.services), que suporta rankMath como product key numa chamada unica (sem steps de OTP, ao contrario de essentialAddons). Para ligar/reactivar a licenca Rank Math Pro em qualquer site do bundle, usar a skill /full-cliente em vez de replicar aqui os comandos do broker — esta skill (/rank-math) fica focada em WP-CLI/dados do plugin ja licenciado.
Recursos
Referencias
references/commands.md— Referencia completa de meta keys, options e modulos
Documentacao Hub
- Manual:
Hub/06-Operacoes/Documentacao/Manuais/WP-CLI/Rank-Math-WP-CLI-Manual-Definitivo.md(17 seccoes) - QR:
Hub/06-Operacoes/Documentacao/Quick-Reference/QR-RankMath-WP-CLI.md - Pesquisa Claude:
Hub/06-Operacoes/Documentacao/Manuais/WP-CLI/Rank-Math-SEO-WP-CLI-Skils-Pesquisa-Claude.md - Pesquisa Gemini:
Hub/06-Operacoes/Documentacao/Manuais/WP-CLI/Rank-Math-SEO-WP-CLI-Skills-Pesquisa-Gemini.md - NotebookLM: WordPress Config CLI (4 fontes)
Fonte: manual completo Rank-Math-WP-CLI-Manual-Definitivo.md (17 seccoes, lido na integra), codigo-fonte includes/modules/ de seo-by-rank-math e seo-by-rank-math-pro lido ao vivo via SSH em descomplicar.pt, wp option get rank_math_modules verificado em produção, achados da auditoria de seguranca/infra 16-08-2026 (CONFIG-Plugins-Referencia.md §7, BUNDLE-Excelencia-WP.md).
Rank Math SEO via WP-CLI | Descomplicar | v2.1.0 | 16-08-2026
Healing Log
Registo de erros conhecidos e como evitá-los. Lido automaticamente antes de executar.
{"date":"","issue":"","fix":"","source":"user|auto"}
Adicionar nova linha após cada erro corrigido.