feat(wordpress): EMCP Tools workflow skills + widget catalogs + pending wordpress skills
- emcp-page-building, emcp-content-ops, emcp-site-audit: EMCP Tools MCP workflows verified live (atomic/legacy interplay, apply-template overwrite risk, create-theme-template goes live immediately, false-positive malware pattern in scan-security, change ledger + rollback) - elementor-pro-widgets: 30+5 native Elementor Pro widgets (curated catalog) - elementskit-widgets / powerpack-widgets: 42 + 97 third-party widgets, widgetType extracted from plugin source (not guessed by convention) - plugin.json bumped 1.2.0 -> 1.3.0, keywords + description updated - commits pending wordpress skills already present as untracked files (emcp-tools, wordfence, wp-activity-log, seguranca-descomplicar, webp-express, wp-fastest-cache, wp-font-perf, wp-meteor, wp-activity-log, redis-object-cache, app-for-cloudflare) and pending edits (rank-math, wp-cli, wp-content-seo-gate)
This commit is contained in:
@@ -0,0 +1,648 @@
|
||||
---
|
||||
name: webp-express
|
||||
description: Gestão do plugin WebP Express (conversão automática de imagens para WebP) via WP-CLI e ficheiro de config em servidores CWP. Cobre localizar o ficheiro de config com hash variável, modos de operação (CDN friendly, Varied image responses, No conversion, Tweaked), reconversão em massa via `wp webp-express convert`, flush de webps, conversores disponíveis (imagemagick/imagick/gd vs cwebp/vips/ffmpeg/graphicsmagick/wpc/ewww) e as respectivas opções próprias, estrutura JSON completa do ficheiro de configuração (qualidade/encoding/near-lossless/alpha-quality por tipo de imagem, cache-control, alter HTML, redirection rules, web service), regras `.htaccess` e a fronteira com o Cloudflare. Usar quando "webp express", "converter imagens webp", "webp nao funciona", "reconverter imagens", "flush webp", "conversor imagemagick gd", "operation mode webp", "cdn friendly webp", "webp quality", "near lossless", "alter html webp", "cache control webp", "web service webp express".
|
||||
---
|
||||
|
||||
# /webp-express — Conversão de imagens para WebP via WP-CLI
|
||||
|
||||
Gestão programática do plugin WebP Express (`webp-express`) em sites WordPress
|
||||
da frota, via WP-CLI no servidor CWP (`server.descomplicar.pt`, SSH porta
|
||||
9443).
|
||||
|
||||
**Fonte:** `CONFIG-Plugins-Referencia.md` §5 (WebP Express) + verificação ao
|
||||
vivo em `emanuelalmeida.pt` (versão `0.25.15`) + leitura completa do
|
||||
código-fonte nesta sessão: `lib/classes/CLI.php`, `lib/classes/CachePurge.php`,
|
||||
`lib/classes/BulkConvert.php`, e **todos** os ficheiros `.inc`/`.php` de
|
||||
`lib/options/options/` (general, conversion-options incl.
|
||||
`converter-options/*.php` por conversor, redirection-rules, serve-options,
|
||||
alter-html, web-service-options, operation-mode.inc) — 43 ficheiros no total.
|
||||
Config JSON completo lido ao vivo do disco (não só campos vistos na UI).
|
||||
|
||||
---
|
||||
|
||||
## Contexto CWP — sempre obrigatório
|
||||
|
||||
```bash
|
||||
PATH=/home/USER/public_html
|
||||
sudo -u USER /usr/local/bin/wp <comando> --path=$PATH
|
||||
```
|
||||
|
||||
**Acesso via SSH:** `ssh -p 9443 root@server.descomplicar.pt` (alias `server`
|
||||
já configurado localmente).
|
||||
|
||||
---
|
||||
|
||||
## 1. Onde vive a configuração — NÃO é `wp_options` normal
|
||||
|
||||
A config principal do WebP Express vive num **ficheiro JSON com nome
|
||||
imprevisível** (hash no nome, muda por instalação/reinstalação):
|
||||
|
||||
```
|
||||
wp-content/webp-express/config/config.<hash>.json
|
||||
```
|
||||
|
||||
**Nunca assumir o hash.** Duas formas de o descobrir, por ordem de
|
||||
preferência:
|
||||
|
||||
```bash
|
||||
# 1. Forma rápida — o hash está guardado numa option (sem precisar de find)
|
||||
wp option get webp-express-config-hash --path=$PATH
|
||||
|
||||
# 2. Confirmar/descobrir via find quando a option não existe ou for preciso
|
||||
# validar o caminho real no disco
|
||||
find $PATH/wp-content/webp-express/config -iname 'config.*.json'
|
||||
```
|
||||
|
||||
O ficheiro em si:
|
||||
|
||||
```bash
|
||||
HASH=$(wp option get webp-express-config-hash --path=$PATH)
|
||||
cat $PATH/wp-content/webp-express/config/config.$HASH.json | python3 -m json.tool
|
||||
```
|
||||
|
||||
### Estado operacional (`wp_options`, separado da config)
|
||||
|
||||
Ao contrário da config, o **estado** vive mesmo em `wp_options` normais,
|
||||
todas com o prefixo `webp-express-`:
|
||||
|
||||
```bash
|
||||
wp option get webp-express-state --format=json --path=$PATH
|
||||
wp option get webp-express-migration-version --path=$PATH
|
||||
wp option get webp-express-config-migrated-cve-2025-11379 --path=$PATH
|
||||
wp option get webp-express-alter-html-options --format=json --path=$PATH
|
||||
```
|
||||
|
||||
`webp-express-state` traz o resumo mais útil de uma só vez:
|
||||
`workingConverterIds`, `workingAndActiveConverterIds`, `configured`,
|
||||
`htaccess-rules-saved-at-some-point`, `active-htaccess-dirs`.
|
||||
|
||||
### ⚠️ Gotcha: `convert_webp_status` e `webp_offset_*` NÃO são do WebP Express
|
||||
|
||||
Numa auditoria com `wp option list --search='*webp*'` aparecem também
|
||||
`convert_webp_status` e vários `webp_offset_*` (`webp_offset_thumbnail`,
|
||||
`webp_offset_large`, etc.). **São opções órfãs de outro plugin** (não
|
||||
presente na lista activa de plugins do site) — não pertencem ao WebP
|
||||
Express e não devem ser lidas/alteradas ao auditar este plugin. Confirmar
|
||||
sempre com `wp plugin list --format=json | grep -i webp` que só
|
||||
`webp-express` está activo antes de interpretar options com "webp" no nome.
|
||||
|
||||
---
|
||||
|
||||
## 2. Modos de operação (`operation-mode`)
|
||||
|
||||
Fonte: `lib/options/options/operation-mode.inc`. Quatro valores possíveis:
|
||||
|
||||
| Valor | Nome na UI | Comportamento |
|
||||
|---|---|---|
|
||||
| `varied-image-responses` | Varied image responses | Redirecciona jpeg/png para webp via `.htaccess`, mas só quando o browser envia `Accept: image/webp`. A mesma URL responde de forma diferente consoante o cliente — **problemático para CDNs que não fazem `Vary` no header `Accept`** |
|
||||
| `cdn-friendly` | CDN friendly | jpeg é **sempre** servido como jpeg; em vez de variar a resposta, o WebP Express reescreve o HTML (`<picture>`/`<img srcset>`) para apontar directamente ao ficheiro `.webp` estático. Melhor HIT ratio em CDN, sem exigir forward do header `Accept` |
|
||||
| `no-conversion` | No conversion | Não converte nada — usado quando outro plugin já faz a conversão e só se quer aproveitar a reescrita de HTML/redirecção do WebP Express |
|
||||
| `tweaked` | Tweaked | Sem preset — todas as opções ficam editáveis individualmente (mostra secções `redirection-rules` e `serve-options` completas, que ficam escondidas nos outros modos); ao voltar a um preset perdem-se as afinações |
|
||||
|
||||
**Verificado em `emanuelalmeida.pt`:** `operation-mode: "cdn-friendly"` —
|
||||
escolha correcta dado o site estar atrás do Cloudflare (evita depender de o
|
||||
Cloudflare fazer `Vary: Accept` correctamente, que nem sempre acontece nos
|
||||
planos gratuitos).
|
||||
|
||||
```bash
|
||||
HASH=$(wp option get webp-express-config-hash --path=$PATH)
|
||||
wp eval "echo json_decode(file_get_contents('wp-content/webp-express/config/config.$HASH.json'))->{'operation-mode'};" --path=$PATH
|
||||
```
|
||||
|
||||
Para mudar de modo é preciso editar o ficheiro JSON directamente (não há
|
||||
comando `wp option patch` — não é uma option serializada) e depois correr
|
||||
`wp webp-express convert --reconvert` para regenerar tudo com as novas
|
||||
definições. **Mutação em produção — nunca fazer sem autorização.**
|
||||
|
||||
**Nota de UI condicional por modo** (relevante ao ler o código de
|
||||
`lib/options/options/general/general.inc`): as secções `scope.inc`,
|
||||
`destination-folder.inc` e `destination-structure.inc` só aparecem quando
|
||||
`operation-mode != 'no-conversion'`; `cache-control.inc` só aparece em
|
||||
`tweaked`, `varied-image-responses` ou `cdn-friendly`. O JSON de config
|
||||
mantém sempre todos os campos gravados, independentemente do que a UI
|
||||
mostra para o modo actual.
|
||||
|
||||
---
|
||||
|
||||
## 3. Reconverter imagens em massa — comando nativo `wp webp-express`
|
||||
|
||||
O plugin regista um comando WP-CLI próprio (`lib/classes/CLI.php`), **não é
|
||||
preciso passar por `wp eval`**. Fonte lida na íntegra nesta sessão — o
|
||||
plugin só regista **dois** subcomandos, não há mais:
|
||||
|
||||
```bash
|
||||
wp help webp-express --path=$PATH
|
||||
```
|
||||
|
||||
```
|
||||
NAME
|
||||
wp webp-express
|
||||
SUBCOMMANDS
|
||||
convert Convert images to webp
|
||||
flushwebp Flush webps
|
||||
```
|
||||
|
||||
### `wp webp-express convert`
|
||||
|
||||
```bash
|
||||
# Ver o que falta converter, sem converter (dry preview por pasta)
|
||||
wp webp-express convert --path=$PATH
|
||||
|
||||
# Converter tudo o que ainda não está convertido (media library + tema)
|
||||
wp webp-express convert uploads --path=$PATH
|
||||
wp webp-express convert themes --path=$PATH
|
||||
|
||||
# Forçar RECONVERSÃO de tudo (substitui webps já existentes)
|
||||
wp webp-express convert uploads --reconvert --path=$PATH
|
||||
|
||||
# Limitar a uma subpasta
|
||||
wp webp-express convert uploads/2026 --path=$PATH
|
||||
|
||||
# Só PNG / só JPEG
|
||||
wp webp-express convert uploads --only-png --path=$PATH
|
||||
wp webp-express convert uploads --only-jpeg --path=$PATH
|
||||
|
||||
# Forçar um conversor específico (ignora o stack de fallback)
|
||||
wp webp-express convert uploads --converter=gd --path=$PATH
|
||||
|
||||
# Sobrepor qualidade/encoding só nesta corrida (não altera a config gravada)
|
||||
wp webp-express convert uploads --quality=75 --encoding=lossy --path=$PATH
|
||||
|
||||
# Sobrepor near-lossless e alpha-quality só nesta corrida
|
||||
wp webp-express convert uploads --near-lossless=60 --path=$PATH
|
||||
wp webp-express convert uploads --alpha-quality=80 --path=$PATH
|
||||
```
|
||||
|
||||
`<location>` aceita `uploads`, `themes`, `plugins`, `wp-content` ou `index`
|
||||
como "raiz de imagem", opcionalmente seguido de `/subpasta`. Sem argumento,
|
||||
lista quantos ficheiros por converter há em cada grupo, sem converter nada.
|
||||
|
||||
**Flags completas do `convert`** (confirmadas em `CLI.php`, docblock
|
||||
`## OPTIONS`):
|
||||
|
||||
| Flag | Efeito | Aplica-se a `max-quality` E `png-quality` |
|
||||
|---|---|---|
|
||||
| `[<location>]` | Restringe a uma raiz de imagem (`uploads`\|`themes`\|`plugins`\|`wp-content`\|`index`), opc. `/subpasta` | — |
|
||||
| `--reconvert` | Reconverte mesmo o que já está convertido | — |
|
||||
| `--only-png` | Só PNG (`image-types = 2`) | — |
|
||||
| `--only-jpeg` | Só JPEG (`image-types = 1`) | — |
|
||||
| `--quality=<n>` | Sobrepõe qualidade (0-100) | Sim — aplica ao mesmo valor `max-quality` e `png-quality` |
|
||||
| `--near-lossless=<n>` | Sobrepõe near-lossless (0-100) | Sim — aplica a `png-near-lossless` e `jpeg-near-lossless` |
|
||||
| `--alpha-quality=<n>` | Sobrepõe alpha-quality (0-100) | Só `alpha-quality` (PNG com transparência) |
|
||||
| `--encoding=<auto\|lossy\|lossless>` | Sobrepõe encoding | Sim — aplica a `png-encoding` e `jpeg-encoding` |
|
||||
| `--converter=<id>` | Força um conversor específico, ignora o stack. Valores válidos: `cwebp \| vips \| ewww \| imagemagick \| imagick \| gmagick \| graphicsmagick \| ffmpeg \| gd \| wpc` | — |
|
||||
|
||||
Nenhuma destas flags altera a config gravada em disco — são só para essa
|
||||
corrida.
|
||||
|
||||
### `wp webp-express flushwebp` — limpar webps gerados
|
||||
|
||||
```bash
|
||||
# Apaga TODOS os .webp gerados (força reconversão no próximo acesso/convert)
|
||||
wp webp-express flushwebp --path=$PATH
|
||||
|
||||
# Só os que vieram de PNG
|
||||
wp webp-express flushwebp --only-png --path=$PATH
|
||||
```
|
||||
|
||||
Internamente chama `CachePurge::purge()` (`lib/classes/CachePurge.php`),
|
||||
que apaga recursivamente `.webp` em três locais: o cache dir
|
||||
(`Paths::getCacheDirAbs()`), o upload dir (só se
|
||||
`destination-folder == 'mingled'`) e o dir de "bigger than source dummy
|
||||
files". Nunca apaga o original de um attachment registado na media library
|
||||
(`MediaLibraryHelper::isRegisteredAttachmentOrThumbnail`) — protecção
|
||||
interna contra apagar acidentalmente ficheiros errados quando modo
|
||||
`mingled` mistura originais e webps na mesma pasta.
|
||||
|
||||
Útil depois de mudar `quality`/`encoding`/conversor na config, antes de
|
||||
correr `convert` de novo — garante que não ficam webps antigos com as
|
||||
definições anteriores misturados com os novos.
|
||||
|
||||
**Alternativa via wp-admin (sem SSH):** Settings → WebP Express → aba
|
||||
"Bulk convert" tem os mesmos botões ("Bulk Convert" → popup de conversão em
|
||||
massa via AJAX; "Delete converted files" → popup que chama
|
||||
`processAjaxPurgeCache()`, o mesmo `CachePurge::purge()` do `flushwebp`).
|
||||
Há ainda um botão "Delete log files" na secção "Enable logging" (ver §7).
|
||||
O WP-CLI é preferível em produção por ser scriptável e não depender de
|
||||
timeout do browser em sites com muitas imagens. **Nota:** a conversão em
|
||||
massa via UI usa sempre as **últimas definições gravadas** (comentário no
|
||||
código-fonte de `bulk-convert.inc`: *"the bulk conversion is using the
|
||||
last saved settings"*) — se acabaste de mudar qualidade/encoding no forms
|
||||
mas ainda não gravaste (Save), o bulk convert usa a versão antiga.
|
||||
|
||||
---
|
||||
|
||||
## 4. Conversores — stack de fallback e opções por conversor
|
||||
|
||||
`webp-express` tenta uma lista ordenada de conversores até um funcionar; cada
|
||||
entrada tem `working: true/false` gravado em `webp-express-state` (testado
|
||||
no arranque, não em cada conversão):
|
||||
|
||||
| Conversor | Estado em `emanuelalmeida.pt` | Nota |
|
||||
|---|---|---|
|
||||
| `imagemagick` (binário CLI) | ✅ `working: true`¹ | Fallback preferido |
|
||||
| `imagick` (extensão PHP) | ✅ `working: true`¹ | |
|
||||
| `gd` (extensão PHP, sempre disponível) | ✅ `working: true` | Último recurso, sempre presente em qualquer instalação PHP |
|
||||
| `cwebp` (binário Google) | ❌ `working: false` | Não instalado no servidor CWP |
|
||||
| `vips` | ❌ `working: false` | Não instalado |
|
||||
| `graphicsmagick`/`gmagick` | ❌ `working: false` | Não instalado |
|
||||
| `ffmpeg` | ❌ `working: false` | Não instalado |
|
||||
| `wpc` (WebP Cloud / Remote WebP Express, API paga ou remota) | ❌ `working: false` | Não configurado (sem API key/URL) |
|
||||
| `ewww` (requer plugin EWWW Image Optimizer) | ❌ `working: false` | Plugin não instalado neste site |
|
||||
|
||||
¹ Nota lida directamente no JSON de config nesta sessão: no bloco
|
||||
`converters[]` do config actual, `imagemagick` e `graphicsmagick` aparecem
|
||||
com `"working": false` (o binário de sistema não responde), enquanto só
|
||||
`gd` tem `"working": true`. O `webp-express-state` (cache separada,
|
||||
recalculada a cada teste de auto-detecção) pode divergir ligeiramente do
|
||||
snapshot gravado no `converters[]` do JSON — **confirmar sempre pelo
|
||||
`webp-express-state` para saber o estado corrente**, o array `converters`
|
||||
do config json é sobretudo a lista de opções por conversor + ordem.
|
||||
|
||||
**Sem impacto operacional** — `gd` cobre 100% dos casos como último
|
||||
recurso; os conversores em falta são apenas alternativas mais
|
||||
rápidas/melhor compressão que não compensam instalar a nível de servidor
|
||||
só para este plugin. Verificar sempre `workingConverterIds` antes de forçar
|
||||
`--converter=X` num `wp webp-express convert` — se `X` não estiver na
|
||||
lista, o comando falha.
|
||||
|
||||
```bash
|
||||
wp option get webp-express-state --format=json --path=$PATH | python3 -c "import json,sys; print(json.load(sys.stdin)['workingConverterIds'])"
|
||||
```
|
||||
|
||||
### Opções específicas por conversor (bloco `converters[].options` no JSON)
|
||||
|
||||
Fonte: `lib/options/options/conversion-options/converter-options/*.php` (um
|
||||
ficheiro por conversor) + o array `converters` do config JSON ao vivo.
|
||||
|
||||
| Conversor | Opções (`options{}`) | Descrição |
|
||||
|---|---|---|
|
||||
| `cwebp` | `use-nice` (bool), `try-common-system-paths` (bool), `try-supplied-binary-for-os` (bool), `method` (0-6), `low-memory`/"set-size"+`size-in-percentage`, `command-line-options` (string livre passada ao binário) | `method`: trade-off velocidade/qualidade (0=rápido, 6=melhor). "Size" força tamanho-alvo em % do original em vez de qualidade (~2.5x mais lento). `command-line-options` aceita qualquer flag do `cwebp` real, ex. `-low_memory -af -f 50 -sharpness 0 -mt` |
|
||||
| `vips` | `smart-subsample` (bool), `preset` (`none`\|`default`\|`photo`\|`picture`\|`drawing`\|`icon`\|`text`) | Preset ajusta várias opções internas consoante o tipo de conteúdo (não sobrepõe qualidade) |
|
||||
| `imagemagick` | `use-nice` (bool) | Executa o binário `convert`; sem outras opções específicas |
|
||||
| `graphicsmagick` (`gmagick`) | `use-nice` (bool) | Executa `gm convert`; sem outras opções específicas |
|
||||
| `ffmpeg` | `use-nice` (bool), `method` (0-6) | Idêntico ao `imagemagick` mas via ffmpeg |
|
||||
| `gd` | `skip-pngs` (bool) | Se `true`, PNGs passam para o próximo conversor da stack (Gd historicamente pior a comprimir PNG e teve bugs de transparência, hoje resolvidos) |
|
||||
| `imagick` | — (sem opções próprias) | "imagick has no special options" no código |
|
||||
| `ewww` | `api-key`, `api-key-2` (fallback) | Serviço cloud pago (ewww.io); fee único, sem custo por conversão webp |
|
||||
| `wpc` (Remote WebP Express / WPC) | `api-version` (0\|1), `api-url`, `secret`/`api-key`, `crypt-api-key-in-transfer` (bool) | Delega a conversão a outra instalação WebP Express ou a um serviço `webp-convert-cloud-service`. Api 0 é legado (v0.1); usar 1 para instâncias WebP Express normais |
|
||||
|
||||
`use-nice`: presente em quase todos os conversores baseados em binário —
|
||||
executa com prioridade reduzida (`nice`) para poupar recursos à custa de
|
||||
conversão ligeiramente mais lenta.
|
||||
|
||||
`Use nice`, `try-common-system-paths`, `try-supplied-binary-for-os`: o
|
||||
plugin traz binários `cwebp` pré-compilados para várias plataformas dentro
|
||||
do próprio plugin (`try-supplied-binary-for-os`) — útil quando o binário de
|
||||
sistema não existe mas o hosting permite `exec()`.
|
||||
|
||||
---
|
||||
|
||||
## 5. Qualidade, encoding, near-lossless e metadata (`conversion-options`)
|
||||
|
||||
Fonte: `lib/options/options/conversion-options/{quality,jpeg,png,metadata}.inc`
|
||||
+ valores ao vivo do JSON de `emanuelalmeida.pt`.
|
||||
|
||||
### 5.1. JPEG → WebP
|
||||
|
||||
| Campo JSON | Valor ao vivo | Descrição |
|
||||
|---|---|---|
|
||||
| `jpeg-encoding` | `"auto"` | `lossy` (sempre lossy) ou `auto` (o plugin experimenta lossy e lossless e fica com o mais pequeno). `Gd`/`Ewww` não suportam `auto` |
|
||||
| `quality-auto` | `true` | Se `true`, tenta detectar a qualidade original do jpeg e usar a mesma no webp (requer imagick/imagemagick/gmagick capazes de detectar qualidade); se `false`, usa `quality-specific` fixo |
|
||||
| `max-quality` | `80` | Tecto para `quality-auto`: mesmo que o jpeg original tenha qualidade mais alta, nunca ultrapassa este valor. Recomendado 50-85 |
|
||||
| `quality-specific` | `70` | Qualidade fixa usada quando `quality-auto=false` OU como fallback quando a detecção de qualidade falhar |
|
||||
| `jpeg-enable-near-lossless` | `true` | Aplica-se quando o encoding resultante é lossless: liga o pré-processamento "near-lossless" em vez de 100% lossless puro. Só suportado por `cwebp` e `vips` |
|
||||
| `jpeg-near-lossless` | `60` | Nível 0 (máximo pré-processamento) a 100 (sem pré-processamento, = lossless puro) |
|
||||
|
||||
### 5.2. PNG → WebP
|
||||
|
||||
| Campo JSON | Valor ao vivo | Descrição |
|
||||
|---|---|---|
|
||||
| `png-encoding` | `"auto"` | `lossless` (default para PNG) ou `auto` (experimenta lossy e lossless, fica com o mais pequeno — não existe opção "sempre lossy" isolada para PNG na UI) |
|
||||
| `png-quality` | `85` | Qualidade quando o resultado é lossy (via `auto`). Recomendado 60-90, tipicamente mais alto que jpeg pois PNG é usado para ícones/gráficos |
|
||||
| `alpha-quality` | `80` | Qualidade específica do canal alfa (transparência), só relevante em encoding lossy com transparência. `Gd`/`Ewww` ignoram esta opção e mantêm o canal alfa sempre lossless |
|
||||
| `png-enable-near-lossless` | `true` | Idêntico ao `jpeg-enable-near-lossless`, mas para PNG |
|
||||
| `png-near-lossless` | `60` | Idêntico ao `jpeg-near-lossless` |
|
||||
|
||||
### 5.3. Metadata
|
||||
|
||||
| Campo JSON | Valor ao vivo | Descrição |
|
||||
|---|---|---|
|
||||
| `metadata` | `"none"` | `none` (não copia EXIF/etc. para o webp — mais pequeno) ou `all` (copia toda a metadata). **`Gd` não suporta cópia de metadata** — ignora esta opção sempre que `Gd` é o conversor efectivo |
|
||||
|
||||
### 5.4. Outras opções gerais de conversão
|
||||
|
||||
| Campo JSON | Valor ao vivo | Descrição |
|
||||
|---|---|---|
|
||||
| `convert-on-upload` | `true` | Converte a imagem (incl. todos os thumbnails gerados) no momento do upload para a media library. Hooka em `handle_upload` e `image_make_intermediate_size`. Pode abrandar o upload em temas com muitos tamanhos de thumbnail |
|
||||
| `image-types` | `3` | Bitmask: `1`=jpeg, `2`=png, `3`=ambos, `0`=desactivado. Controla que tipos são convertidos/processados |
|
||||
| `prevent-using-webps-larger-than-original` | `true` | Webps maiores que o original ficam sempre em disco mas não são usados (nem em `.htaccess` nem em Alter HTML) se esta opção estiver activa. Desde 0.25.5: em Alter HTML com `picture` + `srcset`, só omite o `<source webp>` se **todos** os webps do srcset forem maiores — considerar desactivar se muitas imagens têm srcset |
|
||||
| `enable-logging` | `false` | Grava resultado de cada conversão em `wp-content/webp-express/log/conversions/`. Tem botão dedicado "Delete log files" na UI (popup `purgelogpopup`) |
|
||||
|
||||
---
|
||||
|
||||
## 6. Estrutura completa do ficheiro de configuração (JSON)
|
||||
|
||||
Volcado ao vivo de `emanuelalmeida.pt`
|
||||
(`wp-content/webp-express/config/config.<hash>.json`) — esta é a **lista
|
||||
completa de todas as chaves de topo** que o plugin grava, incluindo as que
|
||||
não aparecem directamente numa única aba da UI:
|
||||
|
||||
```jsonc
|
||||
{
|
||||
// --- Modo e âmbito ---
|
||||
"operation-mode": "cdn-friendly", // varied-image-responses | cdn-friendly | no-conversion | tweaked
|
||||
"scope": ["uploads", "themes"], // subset de: uploads, themes, plugins, wp-content, index
|
||||
"image-types": 3, // bitmask: 1=jpeg 2=png 3=ambos 0=nenhum
|
||||
|
||||
// --- Destino dos ficheiros webp ---
|
||||
"destination-folder": "separate", // separate | mingled
|
||||
"destination-extension": "append", // append (image.jpg.webp) | set (image.webp)
|
||||
"destination-structure": "image-roots", // doc-root | image-roots
|
||||
|
||||
// --- Cache-Control header ---
|
||||
"cache-control": "no-header", // no-header | set | custom
|
||||
"cache-control-custom": "public, max-age=31536000, stale-while-revalidate=604800, stale-if-error=604800",
|
||||
"cache-control-max-age": "one-week", // one-second|one-minute|one-hour|one-day|one-week|one-month|one-year
|
||||
"cache-control-public": false, // true=public, false=private (só usado quando cache-control=set)
|
||||
|
||||
// --- Robustez ---
|
||||
"prevent-using-webps-larger-than-original": true,
|
||||
"enable-logging": false,
|
||||
|
||||
// --- Redirection rules (.htaccess) ---
|
||||
"enable-redirection-to-converter": false, // só editável em modo "tweaked"/"varied-image-responses"
|
||||
"only-redirect-to-converter-on-cache-miss": false,
|
||||
"only-redirect-to-converter-for-webp-enabled-browsers": true,
|
||||
"do-not-pass-source-in-query-string": true,
|
||||
"redirect-to-existing-in-htaccess": false,
|
||||
"forward-query-string": true,
|
||||
"enable-redirection-to-webp-realizer": true, // "criar webp sob pedido" (chave em cdn-friendly)
|
||||
|
||||
// --- Qualidade/encoding jpeg ---
|
||||
"jpeg-encoding": "auto", // lossy | auto
|
||||
"jpeg-enable-near-lossless": true,
|
||||
"jpeg-near-lossless": 60,
|
||||
"quality-auto": true,
|
||||
"max-quality": 80,
|
||||
"quality-specific": 70,
|
||||
|
||||
// --- Qualidade/encoding png ---
|
||||
"png-encoding": "auto", // lossless | auto
|
||||
"png-enable-near-lossless": true,
|
||||
"png-near-lossless": 60,
|
||||
"png-quality": 85,
|
||||
"alpha-quality": 80,
|
||||
|
||||
// --- Stack de conversores, ordem = prioridade ---
|
||||
"converters": [
|
||||
{ "converter": "cwebp", "options": { "use-nice": true, "try-common-system-paths": true, "try-supplied-binary-for-os": true, "method": 6, "low-memory": true, "command-line-options": "" }, "working": false },
|
||||
{ "converter": "vips", "options": { "smart-subsample": false, "preset": "none" }, "working": false },
|
||||
{ "converter": "imagemagick", "options": { "use-nice": true }, "working": false },
|
||||
{ "converter": "graphicsmagick", "options": { "use-nice": true }, "working": false },
|
||||
{ "converter": "ffmpeg", "options": { "use-nice": true, "method": 4 }, "working": false },
|
||||
{ "converter": "wpc", "working": false, "options": { "api-key": "" } },
|
||||
{ "converter": "ewww", "working": false },
|
||||
{ "converter": "imagick", "working": false },
|
||||
{ "converter": "gmagick", "working": false },
|
||||
{ "converter": "gd", "options": { "skip-pngs": false }, "working": true }
|
||||
],
|
||||
|
||||
// --- Metadata / upload automático ---
|
||||
"metadata": "none", // none | all
|
||||
"convert-on-upload": true,
|
||||
|
||||
// --- Serve options (resposta ao browser) ---
|
||||
"fail": "original", // original | 404 | report
|
||||
"success-response": "original", // original | converted
|
||||
|
||||
// --- Alter HTML ---
|
||||
"alter-html": {
|
||||
"enabled": true,
|
||||
"replacement": "picture", // picture | url
|
||||
"hooks": "ob", // content-hooks | ob (output buffering completo da página)
|
||||
"only-for-webp-enabled-browsers": false,
|
||||
"only-for-webps-that-exists": false,
|
||||
"alter-html-add-picturefill-js": true,
|
||||
"hostname-aliases": [] // hostnames extra (CDN) cujas URLs também devem ser reescritas
|
||||
},
|
||||
|
||||
// --- Web service (partilhar conversão com outros sites) ---
|
||||
"web-service": {
|
||||
"enabled": false,
|
||||
"whitelist": [] // [{ip, label, api-key, crypt-in-transfer}, ...]
|
||||
},
|
||||
|
||||
// --- Snapshot de ambiente à data do save (diagnóstico, não editável) ---
|
||||
"environment-when-config-was-saved": { "...": "..." },
|
||||
"base-htaccess-on-these-capability-tests": { "...": "..." },
|
||||
"document-root": "/home/USER/site",
|
||||
"paths-used-in-htaccess": { "wod-url-path": "wp-content/plugins/webp-express/wod/webp-on-demand.php" }
|
||||
}
|
||||
```
|
||||
|
||||
### 6.1. Cache-Control header — detalhe
|
||||
|
||||
Fonte: `lib/options/options/general/cache-control.inc`.
|
||||
|
||||
| `cache-control` | Comportamento |
|
||||
|---|---|
|
||||
| `no-header` | Não define header — deixa o servidor/CDN decidir |
|
||||
| `set` | Usa `cache-control-public` (public/private) + `cache-control-max-age` (preset de duração) para montar o header automaticamente |
|
||||
| `custom` | Usa literalmente a string em `cache-control-custom` — **única forma de definir `stale-while-revalidate`/`stale-if-error`**, não expostos nos presets |
|
||||
|
||||
O texto de ajuda do próprio plugin recomenda `custom` com
|
||||
`stale-while-revalidate`/`stale-if-error` para melhor resiliência em falhas
|
||||
momentâneas do servidor de origem.
|
||||
|
||||
### 6.2. Scope — mapeamento de valores
|
||||
|
||||
Fonte: `lib/options/options/general/scope.inc`. O array `scope[]` é
|
||||
qualquer subconjunto ordenado alfabeticamente de `uploads`, `themes`,
|
||||
`plugins`, `wp-content`, `index`; a UI mapeia combinações comuns para
|
||||
nomes amigáveis:
|
||||
|
||||
| `scope` (array) | Nome na UI |
|
||||
|---|---|
|
||||
| `["uploads"]` | Uploads only |
|
||||
| `["themes"]` | Themes only |
|
||||
| `["themes", "uploads"]` | Uploads and themes |
|
||||
| `["plugins", "themes", "uploads", "wp-content"]` | All content |
|
||||
| `["index", "plugins", "themes", "uploads", "wp-content"]` | Everything (including wp-admin) |
|
||||
| Qualquer outra combinação | Mostrado como "Custom: …" |
|
||||
|
||||
**Verificado em `emanuelalmeida.pt`:** `["uploads", "themes"]` → "Uploads
|
||||
and themes" (plugins/wp-content fora de âmbito).
|
||||
|
||||
### 6.3. Destination folder / extension / structure
|
||||
|
||||
| Opção | Valores | Efeito |
|
||||
|---|---|---|
|
||||
| `destination-folder` | `separate` (pasta dedicada `wp-content/webp-express/webp-images/`) \| `mingled` (webp ao lado do original, só dentro de `uploads`) | `mingled` é recomendado ao combinar com plugins de cache de página que sabem servir por extensão (ex. Cache Enabler), ou com Shortpixel |
|
||||
| `destination-extension` | `append` (`imagem.jpg.webp`) \| `set` (`imagem.webp`) | `set` conflitua se existir `logo.jpg` E `logo.png` na mesma pasta (colidem no mesmo `logo.webp`) |
|
||||
| `destination-structure` | `doc-root` (espelha caminho a partir da doc root) \| `image-roots` (espelha caminho a partir da raiz de imagem — uploads/themes/etc) | Recomendado `image-roots` em hosts com doc root mal configurada; `doc-root` reduz regras de rewrite necessárias em Nginx |
|
||||
|
||||
**Verificado em `emanuelalmeida.pt`:** `destination-folder: "separate"`,
|
||||
`destination-extension: "append"`, `destination-structure: "image-roots"`.
|
||||
|
||||
---
|
||||
|
||||
## 7. Redirection rules (`.htaccess`) — detalhe por opção
|
||||
|
||||
Fonte: `lib/options/options/redirection-rules/*.inc`. Estas opções só são
|
||||
todas editáveis em modo `tweaked`; nos outros modos, o preset do modo
|
||||
decide-as automaticamente (mas o valor gravado no JSON reflecte sempre o
|
||||
que está realmente activo em `.htaccess`).
|
||||
|
||||
| Campo JSON | Descrição |
|
||||
|---|---|
|
||||
| `redirect-to-existing-in-htaccess` | Redirect interno directo para o `.webp` já existente, sem passar por PHP — mais rápido. Regra fica **acima** da regra de conversão |
|
||||
| `enable-redirection-to-converter` | Redirige jpeg/png (não convertidos) para `webp-on-demand.php`, que converte, grava e serve. Regra fica **abaixo** da anterior (só actua se ainda não existir webp) |
|
||||
| `enable-redirection-to-webp-realizer` | "Criar webp files upon request": redirige pedidos por um `.webp` que **ainda não existe** para `webp-realizer.php`, que procura o jpg/png correspondente, converte e serve — permite referenciar webps no HTML antes de existirem fisicamente. É a opção chave em modo `cdn-friendly` |
|
||||
| `only-redirect-to-converter-for-webp-enabled-browsers` | Só actua a regra do `enable-redirection-to-converter` quando o `Accept` header contém `image/webp` |
|
||||
| `only-redirect-to-converter-on-cache-miss` | Condição extra equivalente à funcionalidade usada por `enable-redirection-to-webp-realizer`, mas aplicada ao `enable-redirection-to-converter` — desnecessária se `redirect-to-existing-in-htaccess` já estiver activo |
|
||||
| `do-not-pass-source-in-query-string` | Se `true` (default recomendado), passa o path da imagem por env var em vez de query string, para não disparar firewalls que bloqueiam certas query strings |
|
||||
| `forward-query-string` | Encaminha a query string original do pedido para o script de conversão |
|
||||
|
||||
---
|
||||
|
||||
## 8. Serve options (resposta ao browser após conversão)
|
||||
|
||||
Fonte: `lib/options/options/serve-options/*.inc` — só visível na UI em modo
|
||||
`tweaked`.
|
||||
|
||||
| Campo JSON | Valores | Descrição |
|
||||
|---|---|---|
|
||||
| `fail` | `original` (serve o jpg/png original) \| `404` \| `report` (relatório de erro em texto simples) | Recomendado `original` em produção |
|
||||
| `success-response` | `original` \| `converted` | `converted` envia header `Vary: Accept` (indica que a resposta depende do Accept). Usar `original` se combinado com plugins de cache de página que não sabem variar por Accept (ex. Cache Enabler sem suporte dual-cache) |
|
||||
|
||||
**Verificado em `emanuelalmeida.pt`:** `fail: "original"`,
|
||||
`success-response: "original"`.
|
||||
|
||||
---
|
||||
|
||||
## 9. Alter HTML — detalhe completo
|
||||
|
||||
Fonte: `lib/options/options/alter-html/*.inc`.
|
||||
|
||||
| Campo JSON (`alter-html.*`) | Valores | Descrição |
|
||||
|---|---|---|
|
||||
| `enabled` | bool | Recomendado activar mesmo com redirecção activa: melhora cache em CDN e mantém extensão correcta ao fazer download de imagem |
|
||||
| `replacement` | `picture` \| `url` | **`picture`**: substitui `<img>` por `<picture>` com `<source type="image/webp">` — funciona bem com cache de página, mas pode quebrar CSS `div > img` (usar `div img`). **`url`**: substitui directamente os URLs de imagem (src, srcset, lazy-load attrs, inline styles) — mais abrangente mas não funciona com cache de página excepto Cache Enabler |
|
||||
| `hooks` | `content-hooks` \| `ob` | `content-hooks`: hooka em `the_content`, `the_excerpt`, `post_thumbnail_html`, `get_avatar`, `woocommerce_product_get_image`, `acf_the_content`, `dynamic_sidebar_before/after` — mais leve. `ob`: intercepta a página inteira via output buffering — necessário se o tema/plugin não usa os hooks standard. HTML > 600kb ignora a alteração por protecção de memória |
|
||||
| `only-for-webp-enabled-browsers` | bool | Só relevante com `replacement=url`: só faz a substituição quando o browser suporta webp (evita servir só-webp a browsers antigos sem JS de fallback) |
|
||||
| `only-for-webps-that-exists` | bool | Se `false` ("Reference webps that haven't been converted yet" activo), permite referenciar webps que ainda não existem — requer `enable-redirection-to-webp-realizer` activo para funcionar |
|
||||
| `alter-html-add-picturefill-js` | bool | Só relevante com `replacement=picture`: injecta polyfill `picturefill.js` para browsers sem suporte nativo a `<picture>` (~94% suporte nativo actual) |
|
||||
| `hostname-aliases` | array de strings | Hostnames adicionais (ex. CDN) cujas imagens também devem ser processadas — útil se outro plugin já reescreve URLs para um CDN antes do WebP Express actuar |
|
||||
|
||||
**Verificado em `emanuelalmeida.pt`:** `enabled: true`,
|
||||
`replacement: "picture"`, `hooks: "ob"`,
|
||||
`only-for-webp-enabled-browsers: false`,
|
||||
`only-for-webps-that-exists: false`,
|
||||
`alter-html-add-picturefill-js: true`, `hostname-aliases: []`.
|
||||
|
||||
---
|
||||
|
||||
## 10. Web service — partilhar conversão entre sites
|
||||
|
||||
Fonte: `lib/options/options/web-service-options/*.inc`. Permite que **este**
|
||||
site actue como servidor de conversão remota para outros sites que usam o
|
||||
conversor `wpc`/"Remote WebP Express" (ver §4).
|
||||
|
||||
| Campo JSON (`web-service.*`) | Descrição |
|
||||
|---|---|
|
||||
| `enabled` | Activa o endpoint (URL exposto: `Paths::getWebServiceUrl()`) |
|
||||
| `whitelist[]` | Lista de sites autorizados a usar este endpoint, cada entrada com: `label` (referência própria), `ip` (aceita wildcard `*`, ex. `212.91.*` ou `*` para qualquer IP), `api-key` (chave arbitrária escolhida pelo utilizador, não um segredo gerado), `crypt-api-key-in-transfer` (bool — cifra a api-key no transporte; alguns setups antigos não suportam) |
|
||||
|
||||
**Verificado em `emanuelalmeida.pt`:** `web-service.enabled: false`,
|
||||
`whitelist: []` — não usado como servidor remoto neste site.
|
||||
|
||||
---
|
||||
|
||||
## 11. Bulk convert e cache purge (via UI e via CLI)
|
||||
|
||||
Fonte: `lib/options/options/conversion-options/bulk-convert.inc` +
|
||||
`lib/classes/BulkConvert.php` + `lib/classes/CachePurge.php`.
|
||||
|
||||
- **UI → "Bulk Convert"** dispara AJAX que usa `BulkConvert::getList()` +
|
||||
conversão sequencial das últimas definições **gravadas**. Equivalente
|
||||
CLI: `wp webp-express convert <scope> [--reconvert]`.
|
||||
- **UI → "Delete converted files"** dispara AJAX
|
||||
`CachePurge::processAjaxPurgeCache()`. Equivalente CLI:
|
||||
`wp webp-express flushwebp [--only-png]`.
|
||||
- **UI → "Delete log files"** (dentro da secção "Enable logging") apaga
|
||||
`wp-content/webp-express/log/conversions/*`; sem equivalente CLI
|
||||
dedicado — usar `wp eval` ou apagar directamente via `find`/`rm` se
|
||||
necessário (nunca sem autorização em produção).
|
||||
- O filtro de listagem interno (`BulkConvert::defaultListOptions`) usa
|
||||
sempre `only-unconverted: true` por default (não reconverte o que já
|
||||
existe) e `max-depth: 100` — nunca varre mais de 100 níveis de
|
||||
subpastas.
|
||||
- `CachePurge::purge()` nunca apaga `.webp` que estejam registados como
|
||||
attachment/thumbnail na media library (protecção em modo `mingled`, onde
|
||||
originais e webps partilham pasta).
|
||||
|
||||
---
|
||||
|
||||
## 12. Regras `.htaccess`
|
||||
|
||||
`webp-express-state.configured: true` e
|
||||
`htaccess-rules-saved-at-some-point: true` confirmam que as regras já foram
|
||||
gravadas — normalmente na pasta de cache do próprio plugin
|
||||
(`active-htaccess-dirs: ["cache"]`), não na raiz do site. Isto é o que faz
|
||||
o browser/Cloudflare receberem directamente o ficheiro `.webp` estático em
|
||||
vez de passar por PHP a cada pedido (modo `cdn-friendly`).
|
||||
|
||||
Se `configured: false` ou o site deixar de servir webps depois de uma
|
||||
migração/restauro, o passo de correcção é voltar à página de definições do
|
||||
plugin (wp-admin) e gravar de novo (o botão "Save" regrava o `.htaccess`) —
|
||||
não há comando WP-CLI dedicado a isto; o mais próximo é
|
||||
`wp webp-express flushwebp` seguido de `convert`, que não recria as regras
|
||||
`.htaccess` por si só.
|
||||
|
||||
---
|
||||
|
||||
## 13. Interacção com Cloudflare — quem faz o quê
|
||||
|
||||
**Achado desta sessão, importante para não duplicar trabalho:** a
|
||||
conversão/optimização de imagem feita pelo **Cloudflare "Polish"** está
|
||||
`off` neste site (não editável no plano Free) — o WebP não vem do
|
||||
Cloudflare, vem inteiramente do WebP Express a correr no WordPress. O
|
||||
Cloudflare aqui é só **cache/CDN de distribuição** do ficheiro `.webp` já
|
||||
gerado, não faz qualquer transformação de imagem própria. Não há
|
||||
sobreposição de funcionalidade a resolver, mas também não há optimização
|
||||
de imagem "grátis" via Cloudflare a contar — se o WebP Express falhar a
|
||||
converter, o Cloudflare não compensa.
|
||||
|
||||
Modo `cdn-friendly` foi escolhido precisamente por causa disto: ao reescrever
|
||||
o HTML para apontar directamente ao `.webp` estático (em vez de depender do
|
||||
`Accept` header e do Cloudflare fazer `Vary` correctamente), garante HIT
|
||||
ratio alto no cache do Cloudflare independentemente do plano.
|
||||
|
||||
---
|
||||
|
||||
## Erros comuns
|
||||
|
||||
| Sintoma | Causa | Solução |
|
||||
|---|---|---|
|
||||
| `find`/`cat` no ficheiro de config falha, "No such file" | Hash do nome do ficheiro mudou (reinstalação/migração) | Nunca hardcode o hash — ler sempre `wp option get webp-express-config-hash` primeiro |
|
||||
| Confundir `convert_webp_status`/`webp_offset_*` com definições do WebP Express | Options órfãs de outro plugin já removido, mesmo prefixo textual "webp" | Confirmar `wp plugin list` antes de interpretar qualquer option com "webp" no nome |
|
||||
| `wp webp-express convert --converter=cwebp` falha | Conversor não está na lista `workingConverterIds` (binário não instalado no servidor) | Verificar `webp-express-state` antes de forçar um conversor específico |
|
||||
| Imagens não aparecem como WebP no browser depois de `convert` | `.htaccess` não gravado (`configured: false`) ou modo `varied-image-responses` com CDN sem `Vary: Accept` | Confirmar `configured: true` em `webp-express-state`; preferir `cdn-friendly` atrás de Cloudflare |
|
||||
| Webps antigos com qualidade errada persistem depois de mudar `quality`/`encoding` na config | `convert` normal só converte o que falta, não regenera o que já existe | `wp webp-express flushwebp` seguido de `wp webp-express convert` (ou `convert --reconvert` directo) |
|
||||
| Bulk convert via UI usa qualidade/encoding antigos apesar de ter mudado o form | O bulk convert usa sempre as **últimas definições gravadas** (Save), não o estado não-gravado do formulário | Gravar (Save) antes de disparar "Bulk Convert" |
|
||||
| Metadata (EXIF) desaparece do webp apesar de `metadata: "all"` | `Gd` está a ser o conversor efectivo — Gd não suporta cópia de metadata, ignora sempre a opção | Confirmar qual conversor está `working`/activo antes de assumir que `metadata: "all"` está a ser respeitado |
|
||||
| Alpha quality/near-lossless parecem não ter efeito | Conversor efectivo (`Gd`/`Ewww`) não suporta essas opções — são ignoradas silenciosamente | Confirmar o conversor: near-lossless só em `cwebp`/`vips`; alpha-quality ignorado por `Gd`/`Ewww` |
|
||||
| Selector CSS `div > img` deixa de funcionar depois de activar Alter HTML | `replacement: "picture"` insere um elemento `<picture>` extra entre o `div` e o `img` | Usar selector `div img` (descendente) em vez de `div > img` (filho directo), ou mudar para `replacement: "url"` |
|
||||
|
||||
---
|
||||
|
||||
**Fonte:** `CONFIG-Plugins-Referencia.md` §5 + auditoria ao vivo original em
|
||||
`emanuelalmeida.pt` + expansão nesta sessão com leitura completa do
|
||||
código-fonte: `lib/classes/CLI.php`, `CachePurge.php`, `BulkConvert.php`, e
|
||||
os 43 ficheiros `.inc`/`.php` de `lib/options/options/` (general,
|
||||
conversion-options + converter-options/*.php, redirection-rules,
|
||||
serve-options, alter-html, web-service-options, operation-mode.inc). Config
|
||||
JSON completo (`config.<hash>.json`) lido ao vivo do disco — todas as
|
||||
chaves de topo documentadas em §6 vêm directamente desse ficheiro, não só
|
||||
das que a UI mostra por modo.
|
||||
Reference in New Issue
Block a user