feat: sync all plugins, skills, agents updates
New plugins: core-tools New skills: auto-expense, ticket-triage, design, security-check, aiktop-tasks, daily-digest, imap-triage, index-update, mindmap, notebooklm, proc-creator, tasks-overview, validate-component, perfex-module, report, calendar-manager New agents: design-critic, design-generator, design-lead, design-prompt-architect, design-researcher, compliance-auditor, metabase-analyst, gitea-integration-specialist Updated: all plugin configs, knowledge datasets, existing skills Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
417
wordpress/skills/elementor/references/automation.md
Normal file
417
wordpress/skills/elementor/references/automation.md
Normal file
@@ -0,0 +1,417 @@
|
||||
# Elementor — Automação Programática e Pipelines
|
||||
|
||||
Referência técnica para manipular o Elementor sem GUI: WP-CLI, MySQL, REST API, PHP Hooks, Kits e CSS.
|
||||
|
||||
---
|
||||
|
||||
## 1. WP-CLI + Elementor (CWP)
|
||||
|
||||
### Formato Obrigatório CWP
|
||||
|
||||
```bash
|
||||
PHP="/opt/alt/php-fpm83/usr/bin/php"
|
||||
WP="$PHP /usr/local/bin/wp --allow-root --path=/home/USER/public_html"
|
||||
```
|
||||
|
||||
### Comandos Essenciais
|
||||
|
||||
```bash
|
||||
# Regenerar CSS (SEMPRE após qualquer alteração programática)
|
||||
$WP elementor flush-css --regenerate
|
||||
|
||||
# Substituição segura de URLs (evita corrupção JSON)
|
||||
# NUNCA usar wp search-replace directamente em _elementor_data
|
||||
$WP elementor replace-urls $URL_OLD $URL_NEW
|
||||
$WP search-replace $URL_OLD $URL_NEW --skip-columns=guid
|
||||
|
||||
# Importar Kit (design system completo)
|
||||
$WP elementor kit import /tmp/kit.zip \
|
||||
--include=site-settings,templates,content \
|
||||
--overrideConditions=all
|
||||
|
||||
# Sincronizar esquema BD após update do plugin
|
||||
$WP elementor update db
|
||||
|
||||
# Modo manutenção
|
||||
$WP maintenance-mode activate
|
||||
$WP maintenance-mode deactivate
|
||||
```
|
||||
|
||||
### Pipeline de Deploy Completo
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
# Pipeline de rebranding via WP-CLI (CWP)
|
||||
PHP="/opt/alt/php-fpm83/usr/bin/php"
|
||||
SITE_PATH="/home/USER/public_html"
|
||||
KIT_PATH="/tmp/rebranding-2026.zip"
|
||||
URL_OLD="https://staging.agencia.com"
|
||||
URL_NEW="https://www.producao.com"
|
||||
WP="$PHP /usr/local/bin/wp --allow-root --path=$SITE_PATH"
|
||||
|
||||
$WP maintenance-mode activate
|
||||
$WP elementor kit import $KIT_PATH --include=site-settings,templates,content --overrideConditions=all
|
||||
$WP elementor replace-urls $URL_OLD $URL_NEW
|
||||
$WP search-replace $URL_OLD $URL_NEW --skip-columns=guid
|
||||
$WP elementor flush-css --regenerate
|
||||
$WP elementor update db
|
||||
$WP maintenance-mode deactivate
|
||||
```
|
||||
|
||||
### Avaliação do Método
|
||||
|
||||
| Critério | Análise |
|
||||
|----------|---------|
|
||||
| Complexidade | Baixa — sintaxe documentada, comportamento previsível |
|
||||
| Segurança | Alta — invoca internos do WordPress, risco apenas em SSH |
|
||||
| Usar quando | Deploy, purga de cache, migração de URLs, sincronização BD |
|
||||
|
||||
---
|
||||
|
||||
## 2. Manipulação Directa via MySQL
|
||||
|
||||
### Estrutura _elementor_data
|
||||
|
||||
O Elementor guarda layouts como JSON em `wp_postmeta`. Três meta keys obrigatórias:
|
||||
|
||||
| Meta Key | Valor |
|
||||
|----------|-------|
|
||||
| `_elementor_edit_mode` | `builder` |
|
||||
| `_elementor_template_type` | `wp-page`, `kit`, `header`, `footer` |
|
||||
| `_elementor_data` | JSON array com toda a árvore de widgets |
|
||||
|
||||
### Estrutura JSON Interna
|
||||
|
||||
```json
|
||||
[{
|
||||
"id": "3130e2cf",
|
||||
"elType": "container",
|
||||
"isInner": false,
|
||||
"settings": { ... },
|
||||
"elements": [{
|
||||
"id": "a1b2c3d4",
|
||||
"elType": "widget",
|
||||
"widgetType": "button",
|
||||
"settings": {
|
||||
"text": "Clique aqui",
|
||||
"link": { "url": "https://exemplo.com" }
|
||||
}
|
||||
}]
|
||||
}]
|
||||
```
|
||||
|
||||
### Query MySQL com JSON_REPLACE
|
||||
|
||||
```sql
|
||||
-- Substituição cirúrgica num widget específico
|
||||
-- SEMPRE fazer backup antes
|
||||
UPDATE wp_postmeta
|
||||
SET meta_value = JSON_REPLACE(
|
||||
meta_value,
|
||||
'$.elements.elements.settings.link.url',
|
||||
'https://www.novo-destino.com/contacto'
|
||||
)
|
||||
WHERE meta_key = '_elementor_data'
|
||||
AND post_id IN (1042, 1045, 1088);
|
||||
|
||||
-- OBRIGATÓRIO após qualquer UPDATE directo:
|
||||
-- Executar 'wp elementor flush-css --regenerate' via WP-CLI
|
||||
```
|
||||
|
||||
### Regra Crítica: NUNCA wp search-replace
|
||||
|
||||
```bash
|
||||
# ERRADO — corrompe JSON silenciosamente (whitespace of death)
|
||||
wp search-replace 'http://antigo.com' 'https://novo.com'
|
||||
|
||||
# CORRECTO — usa lógica nativa do Elementor
|
||||
wp elementor replace-urls 'http://antigo.com' 'https://novo.com'
|
||||
```
|
||||
|
||||
### Avaliação do Método
|
||||
|
||||
| Critério | Análise |
|
||||
|----------|---------|
|
||||
| Complexidade | Alta — parsing JSON, funções MySQL JSON_* |
|
||||
| Segurança | Muito Baixa — sem validação, um char inválido corrompe a página |
|
||||
| Usar quando | Auditoria forense, extracção analítica em massa (10.000+ posts) |
|
||||
|
||||
---
|
||||
|
||||
## 3. REST API Custom Endpoint
|
||||
|
||||
Para agentes externos (n8n, Make, Python) manipularem layouts via HTTP.
|
||||
|
||||
### Registar Endpoint (functions.php ou plugin MU)
|
||||
|
||||
```php
|
||||
<?php
|
||||
add_action('rest_api_init', function () {
|
||||
register_rest_route('agencia-ai/v1', '/atualizar-layout', [
|
||||
'methods' => 'POST',
|
||||
'callback' => 'ai_agent_update_elementor_layout',
|
||||
'permission_callback' => function() {
|
||||
return current_user_can('edit_pages');
|
||||
}
|
||||
]);
|
||||
});
|
||||
|
||||
function ai_agent_update_elementor_layout(WP_REST_Request $request) {
|
||||
$post_id = absint($request->get_param('post_id'));
|
||||
$json_data = $request->get_param('elementor_json');
|
||||
|
||||
// wp_slash é OBRIGATÓRIO — protege JSON de corrupção de escape
|
||||
update_post_meta($post_id, '_elementor_data', wp_slash(json_encode($json_data)));
|
||||
update_post_meta($post_id, '_elementor_edit_mode', 'builder');
|
||||
|
||||
// Invalidação de cache OBRIGATÓRIA
|
||||
delete_post_meta($post_id, '_elementor_css');
|
||||
if (did_action('elementor/loaded')) {
|
||||
\Elementor\Plugin::$instance->files_manager->clear_cache();
|
||||
}
|
||||
|
||||
return rest_ensure_response([
|
||||
'status' => 'success',
|
||||
'post_id' => $post_id
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
### Autenticação
|
||||
|
||||
```bash
|
||||
# Via Application Passwords (WordPress 5.6+)
|
||||
curl -X POST https://site.pt/wp-json/agencia-ai/v1/atualizar-layout \
|
||||
-H "Authorization: Basic $(echo -n 'user:app-password' | base64)" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"post_id": 2607, "elementor_json": [...]}'
|
||||
```
|
||||
|
||||
### Avaliação do Método
|
||||
|
||||
| Critério | Análise |
|
||||
|----------|---------|
|
||||
| Complexidade | Média — endpoint PHP + formatar JSON _elementor_data válido |
|
||||
| Segurança | Alta — usa permissões WordPress + HTTPS |
|
||||
| Usar quando | Webhooks, n8n/Make, geração de páginas a partir de CRM |
|
||||
|
||||
---
|
||||
|
||||
## 4. PHP Hooks — Dynamic Tags
|
||||
|
||||
Para conteúdo que se actualiza em runtime sem reescrever JSON.
|
||||
|
||||
### Registar Dynamic Tag
|
||||
|
||||
```php
|
||||
<?php
|
||||
// Herdeiro da classe base de Dynamic Tags
|
||||
class IA_Agente_Metrica_Tag extends \Elementor\Core\DynamicTags\Tag {
|
||||
|
||||
public function get_name() { return 'tag-agente-ia'; }
|
||||
public function get_title() { return 'Relatório Dinâmico IA'; }
|
||||
public function get_group() { return 'text'; }
|
||||
public function get_categories() { return [\Elementor\Modules\DynamicTags\Module::TEXT_CATEGORY]; }
|
||||
|
||||
// Render lê do Transients API — o agente IA popula externamente
|
||||
public function render() {
|
||||
$dados = get_transient('ia_agente_ultima_metrica');
|
||||
echo $dados ? wp_kses_post($dados) : 'A aguardar sincronização...';
|
||||
}
|
||||
}
|
||||
|
||||
// Registar
|
||||
add_action('elementor/dynamic_tags/register', function($manager) {
|
||||
$manager->register(new IA_Agente_Metrica_Tag());
|
||||
});
|
||||
```
|
||||
|
||||
### Padrão: Agente IA actualiza Transient
|
||||
|
||||
```php
|
||||
// Agente IA executa isto remotamente (via eval-file ou endpoint)
|
||||
set_transient('ia_agente_ultima_metrica', '<p>Taxa de conversão: 4.2%</p>', DAY_IN_SECONDS);
|
||||
```
|
||||
|
||||
### Avaliação do Método
|
||||
|
||||
| Critério | Análise |
|
||||
|----------|---------|
|
||||
| Complexidade | Alta — OOP PHP, Event Loop WordPress, DynamicTags |
|
||||
| Segurança | Muito Alta — lógica server-side, CI/CD, sem exposição JSON |
|
||||
| Usar quando | Conteúdo em tempo real (cotações, stock, métricas) — requer Elementor **Pro** |
|
||||
|
||||
---
|
||||
|
||||
## 5. Site Kits — Estrutura e Geração
|
||||
|
||||
### Estrutura ZIP de um Kit
|
||||
|
||||
```
|
||||
kit.zip
|
||||
├── manifest.json # Índice mestre — mapeamento de todos os ficheiros
|
||||
├── site-settings.json # Cores globais, tipografia, configurações do tema
|
||||
├── header-template.json # Template de cabeçalho
|
||||
├── footer-template.json # Template de rodapé
|
||||
└── page-template.json # Templates de páginas
|
||||
```
|
||||
|
||||
### manifest.json (estrutura mínima)
|
||||
|
||||
```json
|
||||
{
|
||||
"templates": [
|
||||
{
|
||||
"title": "Header Principal",
|
||||
"type": "header",
|
||||
"fileName": "header-template.json"
|
||||
}
|
||||
],
|
||||
"site_settings": {
|
||||
"title": "Site Settings",
|
||||
"fileName": "site-settings.json"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Geração em Python
|
||||
|
||||
```python
|
||||
import json, zipfile, os
|
||||
|
||||
kit_settings = {
|
||||
"version": "0.4",
|
||||
"title": "Site Settings",
|
||||
"settings": {
|
||||
"system_colors": [
|
||||
{"_id": "primary", "title": "Primária", "color": "#1E40AF"},
|
||||
{"_id": "secondary", "title": "Secundária", "color": "#10B981"}
|
||||
],
|
||||
"system_typography": [
|
||||
{"_id": "primary", "title": "Principal", "typography_font_family": "Inter"}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
manifest = {
|
||||
"templates": [],
|
||||
"site_settings": {"title": "Site Settings", "fileName": "site-settings.json"}
|
||||
}
|
||||
|
||||
os.makedirs('/tmp/kit_build', exist_ok=True)
|
||||
|
||||
with open('/tmp/kit_build/site-settings.json', 'w') as f:
|
||||
json.dump(kit_settings, f)
|
||||
|
||||
with open('/tmp/kit_build/manifest.json', 'w') as f:
|
||||
json.dump(manifest, f)
|
||||
|
||||
with zipfile.ZipFile('/tmp/agencia-kit.zip', 'w') as z:
|
||||
z.write('/tmp/kit_build/manifest.json', 'manifest.json')
|
||||
z.write('/tmp/kit_build/site-settings.json', 'site-settings.json')
|
||||
|
||||
# Importar via WP-CLI (CWP)
|
||||
# /opt/alt/php-fpm83/usr/bin/php /usr/local/bin/wp elementor kit import /tmp/agencia-kit.zip \
|
||||
# --include=site-settings,templates --overrideConditions=all \
|
||||
# --allow-root --path=/home/USER/public_html
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. CSS — Invalidação de Cache
|
||||
|
||||
### Localização dos Ficheiros CSS
|
||||
|
||||
```
|
||||
wp-content/uploads/elementor/css/post-{ID}.css # CSS por página
|
||||
wp-content/uploads/elementor/css/global.css # CSS global
|
||||
```
|
||||
|
||||
### Invalidação Programática (PHP)
|
||||
|
||||
```php
|
||||
// Após qualquer alteração directa a _elementor_data ou post_meta
|
||||
if (did_action('elementor/loaded')) {
|
||||
\Elementor\Plugin::$instance->files_manager->clear_cache();
|
||||
}
|
||||
|
||||
// Alternativa: apagar meta específica
|
||||
delete_post_meta($post_id, '_elementor_css');
|
||||
```
|
||||
|
||||
### Rebranding Global — Kit Activo
|
||||
|
||||
```php
|
||||
// Obter ID do kit activo
|
||||
$kit_id = get_option('elementor_active_kit');
|
||||
|
||||
// Ler configurações globais
|
||||
$settings = get_post_meta($kit_id, '_elementor_page_settings', true);
|
||||
|
||||
// Alterar cor primária
|
||||
if (!empty($settings['system_colors'])) {
|
||||
foreach ($settings['system_colors'] as &$cor) {
|
||||
if ($cor['_id'] === 'primary') {
|
||||
$cor['color'] = '#FF0000';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Guardar (wp_slash protege o JSON)
|
||||
update_post_meta($kit_id, '_elementor_page_settings', $settings);
|
||||
|
||||
// Invalidar cache CSS
|
||||
if (did_action('elementor/loaded')) {
|
||||
\Elementor\Plugin::$instance->files_manager->clear_cache();
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Regras Críticas e Riscos
|
||||
|
||||
### Nunca fazer
|
||||
|
||||
| Erro | Consequência | Correcto |
|
||||
|------|-------------|----------|
|
||||
| `wp search-replace` em `_elementor_data` | Corrupção silenciosa do JSON, layout desaparece | `wp elementor replace-urls` |
|
||||
| UPDATE MySQL sem flush-css | CSS desactualizado, design dessincronizado | Sempre `wp elementor flush-css --regenerate` |
|
||||
| `update_post_meta` sem `wp_slash()` | Corrupção de escapes no JSON | `wp_slash(json_encode($data))` |
|
||||
| Múltiplos agentes a editar o mesmo post | Sobreposição de dados | Locks ou filas de processamento |
|
||||
|
||||
### IDs de Widgets São Aleatórios
|
||||
|
||||
Os IDs de nós JSON (ex: `"id":"3130e2cf"`) são alfanuméricos aleatórios. Para manipular um widget específico via MySQL ou REST API:
|
||||
|
||||
1. Fazer parsing da árvore JSON completa primeiro
|
||||
2. Encontrar o widget pelo `widgetType` ou conteúdo
|
||||
3. Só então operar no ID correcto
|
||||
|
||||
### Limitações Elementor Free vs Pro
|
||||
|
||||
| Funcionalidade | Free | Pro |
|
||||
|----------------|------|-----|
|
||||
| `wp elementor flush-css` | ✅ | ✅ |
|
||||
| `wp elementor kit import` | ✅ | ✅ |
|
||||
| Dynamic Tags | ❌ | ✅ |
|
||||
| Theme Builder (header/footer) | ❌ | ✅ |
|
||||
|
||||
---
|
||||
|
||||
## 8. MCP Elementor (Integração Futura)
|
||||
|
||||
O projecto **Ultimate Elementor MCP** expõe ~60 ferramentas para manipulação via linguagem natural:
|
||||
|
||||
- `create_container`, `create_heading`, `delete_element`
|
||||
- `get_page_structure` — lê árvore JSON (resolve problema dos IDs aleatórios)
|
||||
- `update_widget_settings`
|
||||
|
||||
**Autenticação:** Application Passwords ou JWT (mesma arquitectura do REST API).
|
||||
|
||||
**Quando usar:** Assistentes conversacionais, automações complexas onde formatar JSON raw em Python seria impraticável.
|
||||
|
||||
**Referência:** [Ultimate Elementor MCP — LobeHub](https://lobehub.com/mcp/mbrown1837-ultimate-elementor-mcp)
|
||||
|
||||
---
|
||||
|
||||
*Automação Elementor | Descomplicar® | Baseado em: Manipulação Programática do Elementor — Automação via IA | 18-02-2026*
|
||||
Reference in New Issue
Block a user