Dify foi removido 06-03-2026. Skills brainstorm/discover ainda referenciam-no no corpo. Bump v1.2 + nota top-of-file. Reescrita workflow para próxima sessão. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
40 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, validação e rollback. Usar quando "rank math", "seo cli", "schema markup", "redirects seo", "instant indexing", "indexnow", "seo bulk", "rankmath pro". |
/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 (176.9.3.158) | 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
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 | sim | 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
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)
Rank Math SEO via WP-CLI | Descomplicar | v2.0.0 | 29-03-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.