Skill mcp-webp-express: MCP dedicado (webpx) para WebP Express multi-site via WP-CLI/SSH, mesmo padrao mcp-wpfc. webp-express/SKILL.md: nova seccao 14 documentando o MCP construido e testado ao vivo em emanuelalmeida.pt.
40 KiB
name, description
| name | description |
|---|---|
| webp-express | 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`, a fronteira com o Cloudflare, e o MCP `webpx` construído para gestão programática multi-site (§14). 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", "mcp webp express", "webpx". |
/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
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:
# 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:
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-:
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).
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:
wp help webp-express --path=$PATH
NAME
wp webp-express
SUBCOMMANDS
convert Convert images to webp
flushwebp Flush webps
wp webp-express convert
# 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
# 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.
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:
{
// --- 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 — usarwp evalou apagar directamente viafind/rmse necessário (nunca sem autorização em produção). - O filtro de listagem interno (
BulkConvert::defaultListOptions) usa sempreonly-unconverted: truepor default (não reconverte o que já existe) emax-depth: 100— nunca varre mais de 100 níveis de subpastas. CachePurge::purge()nunca apaga.webpque estejam registados como attachment/thumbnail na media library (protecção em modomingled, 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.
14. MCP webpx — gestão programática (construído 19-08-2026)
Existe um MCP dedicado (mcp-webp-express, registado como webpx em
~/.omp/agent/mcp.json) que expõe as operações deste documento como tools,
multi-site (todos os 8 aliases do bundle Descomplicar, mesmo padrão do
wpfc/mcp-element-pack): spawn("ssh", ...), valor em base64 sobre
stdin, sem ledger/rollback (fora do âmbito — ver emcp-tools para mudanças
que precisem disso).
Diferença chave vs os outros MCPs da frota: a config deste plugin vive
num ficheiro com hash no nome (§1), não numa wp_option — o MCP resolve o
hash via webp-express-config-hash em cada chamada (nunca hardcoded) e
preserva owner:group:permissões do ficheiro ao escrever (a ligação SSH
corre como root; sem isto o wp-admin do site deixaria de conseguir gravar
as próprias definições). webp-express-state também exigiu tratamento
especial: o plugin grava-a como STRING JSON, não como array — um
--format=json ingénuo devolve JSON duas vezes codificado.
Tools (9)
webpx_list_sites— sites conhecidos.webpx_get_status/webpx_get_state— plugin instalado/activo/versão +webp-express-state(workingConverterIds, configured, htaccess-rules- saved-at-some-point).webpx_get_config/webpx_set_config— ficheiroconfig.<hash>.jsoncompleto (§6).webpx_get_converters/webpx_set_converter_options— stack de conversores (§4), opções por conversor + reordenação.webpx_convert—wp webp-express convert(§3).webpx_flushwebp—wp webp-express flushwebp(§3).
Guarda-corpos
webpx_set_configrecusa gravar as chaves de diagnóstico só-leitura de §6 (environment-when-config-was-saved,base-htaccess-on-these-capability-tests,document-root,paths-used-in-htaccess).webpx_set_configdevolve um aviso explícito quando a chave alterada só tem efeito via.htaccess(operation-mode, scope, image-types, destination-*, redirection rules) — regenerar essas regras continua a exigir abrir wp-admin → Save uma vez (§12), sem equivalente WP-CLI.
Testado ao vivo em emanuelalmeida.pt (19-08-2026): leitura completa
da config, escrita+leitura de volta com enable-logging (revertido),
escrita+leitura de volta de gd.skip-pngs via webpx_set_converter_options
(revertido), bloqueio confirmado ao tentar gravar document-root, convert
em modo preview (0 ficheiros por converter, config já estável). Owner:group
do ficheiro de config confirmado ealmeida:ealmeida 644 antes e depois da
escrita. webpx_flushwebp e convert com location/reconvert reais não
foram exercidos contra produção (mesmo padrão de comando já validado via
convert em dry-run — risco desnecessário para a validação).
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.