--- name: rank-math description: 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](https://notebooklm.google.com/notebook/fb2f26bd-8cb0-4d4c-bafc-4f1ebb51c51d) **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: "" }) ``` --- ## 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 ```bash # Formato base (PHP 8.3) /opt/alt/php-fpm83/usr/bin/php /usr/local/bin/wp --allow-root --path=/home/USER/public_html # Alias wp83 --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: ```bash 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:** ```bash 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 ```bash 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 ```bash 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 ```bash # 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) ```bash # 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 ```bash # 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 ```bash # 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. ```bash # 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 ```bash # 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 ```json { "metadata": {"title": "Article", "type": "custom", "shortcode": "s-UNIQUE", "isPrimary": "1"}, "@type": "Article", "headline": "%seo_title%", "description": "%seo_description%" } ``` - `type: "template"` — herda globals | `type: "custom"` — personalizado - `isPrimary: "1"` — schema principal do post - Free: 1 schema/post | PRO: ilimitados ### Criar schemas ```bash # 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 ```bash # 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) ```bash # 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 ```bash # 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) ```bash # 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):** ```nginx 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) ```bash # 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) ```bash # 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) ```bash # 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) ```bash # 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 ```bash # 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) ```bash 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) ```bash # 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 ```bash # Modificar titulo via filtro (persistente via rank-math.php) wp eval ' file_put_contents(get_stylesheet_directory() . "/rank-math.php", "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 ```bash # 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. ```bash # 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 ```bash # 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 '