Esta especificação define o lote de trabalho req-026 (BATCH-026) para o Engenheiro Executor. O escopo abrange duas tarefas principais:
-
Ajuste nos Prompts de Modo de IA (Destaques e Galerias): Atualização das instruções de prompt em português e inglês para documentar o bloco condicional opcional
<!-- no-item < -->no destaques, permitir variáveis adicionais nos destaques, e incluir as variáveis de link individual ([[item#link-url]],[[item#link-target]],[[item#link-css-classes]]) com a regra de âncora<a>obrigatória nas galerias. -
Preservação de Código HTML/CSS Modificado nos Editores: Correção do bug nos módulos de Menus, Galerias e Destaques (Publisher Highlights) no qual, ao carregar a tela de edição ou clonagem, as modificações de HTML/CSS salvas no banco de dados são sobrescritas pela carga automática (
loadTemplate) do modelo padrão (template_id).
1. Contexto e Requisitos
1.1 Atualização de Prompts dos Modos de IA (Destaques e Galerias)
-
Destaques (
publisher-highlights): Os prompts (em português e inglês) carecem de menção ao bloco opcional<!-- no-item < -->, que renderiza o estado vazio quando o destaque não tiver publicações a exibir (mecanismo processado pelopublisher-highlights.widget.php). Também é necessário esclarecer que o usuário pode solicitar e definir variáveis personalizadas adicionais no padrão[[item#nome_da_variavel]]. -
Galerias (
galleries): Os prompts (em português e inglês) não listam as variáveis de link individual por imagem ([[item#link-url]],[[item#link-target]],[[item#link-css-classes]]) implementadas no BATCH-024. Isso faz a IA gerar o loop<!-- item < -->apenas com a tag<img>e sem a tag de âncora<a>. Devemos incluir a especificação destas variáveis e uma regra obrigatória de que cada imagem gerada pela IA deve estar envelopada pela tag<a>com os placeholders de link correspondentes.
1.2 Preservação de Código HTML/CSS Customizado
-
Problema: Nos módulos
menus,galleriesepublisher-highlights, a tela de edição/clonagem exibe no dropdown de templates (template_id) o modelo base selecionado. Na inicialização do DOM, os scripts JS de cada módulo identificam a presença de um valor no select do template e chamam a funçãoloadTemplate(). Essa função faz uma requisição AJAX (template-load) e preenche os editores CodeMirror com o HTML e CSS padrões originais daquele template, deletando e sobrescrevendo as alterações salvas do registro. -
Sugestão de Solução:
-
No PHP, ao construir as opções do select de templates (
#template_id_options#) para as telas de edição ou clonagem, se o registro possuir código HTML ou CSS customizado no banco de dados: gerar duas opções para o mesmo template: a original (ex:<option value="menus-horizontal-navbar">Menu Horizontal</option>) e a customizada com o sufixo-modificadoselecionada por padrão (ex:<option value="menus-horizontal-navbar-modificado" selected>Menu Horizontal - (Modificado)</option>). -
No JavaScript, no carregamento da página:
-
Ler o valor do select de templates. Se ele possuir o sufixo
-modificado, NÃO dispararloadTemplate(), mantendo o código HTML e CSS injetado pelo PHP nos textareas originais do banco de dados. -
Guardar o HTML e CSS originais de page load em variáveis de cache cache (ex:
initialHtmleinitialCss). -
Ao detectar mudanças no select do template:
-
Se o usuário alterar a seleção para a opção limpa (sem o sufixo
-modificado), disparar oloadTemplate()via AJAX para sobrescrever os editores com o template padrão de forma dinâmica. -
Se o usuário retornar para a opção
-modificado, restaurar os editores com o código customizado original armazenado no cache.
-
-
Antes do envio do formulário (evento
submit) ou da serialização (currentSchemaOut()), remover o sufixo-modificadodo valor do template do input (ou do JSON de dados) para que o banco de dados armazene apenas o identificador limpo do template (evitando a gravação de strings com-modificadono banco de dados e mantendo a compatibilidade das queries).
-
-
2. Especificações de Alteração de Código
2.1 Ajuste dos Prompts de Modo de IA
[MODIFY] publisher-highlights.md (pt-br) e publisher-highlights.md (en)
-
Instrução de Bloco Vazio: Adicionar explicação sobre o bloco opcional de ausência de itens:
Caso o destaque não tenha publicações para exibir, o motor de templates renderizará opcionalmente o bloco de fallback. Se julgar necessário ou se o usuário pedir, envolva esse trecho no bloco opcional:<!-- no-item < --> ...HTML exibido quando não houver publicações/itens... <!-- no-item > -->
-
Variáveis Adicionais do Usuário: Adicionar nota informando que o usuário pode fornecer e requerer variáveis adicionais, e que elas devem ser geradas no padrão
[[item#nome_da_variavel]](em inglês usar[[item#variable_name]]):-
Português: "O usuário também pode solicitar e fornecer variáveis adicionais personalizadas além das listadas na seção de variáveis disponíveis. Nesses casos, gere-as seguindo o mesmo padrão
[[item#nome_da_variavel_adicional]]." -
Inglês: "The user may also request and specify additional custom variables beyond the ones listed in the available variables section. In these cases, generate them following the same pattern
[[item#additional_variable_name]]."
-
[MODIFY] galleries.md (pt-br) e galleries.md (en)
-
Regra de Link Obrigatória: Adicionar instrução explícita sobre a presença de tags de âncora envolvendo imagens:
-
Português: "REGRA OBRIGATÓRIA DE LINKS NAS IMAGENS: Cada imagem (ou slide/card) dentro do loop
<!-- item < -->deve conter uma tag de âncora<a>envolvendo a imagem<img>. Use os placeholdershref="[[item#link-url]]",target="[[item#link-target]]"eclass="[[item#link-css-classes]]"nesta âncora para garantir a funcionalidade de clique individual." -
Inglês: "MANDATORY IMAGE LINKS RULE: Each image (or slide/card) inside the
<!-- item < -->loop must contain an anchor<a>tag wrapping the<img>element. Use the placeholdershref="[[item#link-url]]",target="[[item#link-target]]", andclass="[[item#link-css-classes]]"in this anchor to ensure individual click functionality."
-
-
Lista de Variáveis Disponíveis: Adicionar os novos placeholders no bloco de variáveis de imagem:
-
Português:
- `[[item#link-url]]` — URL de destino do link da imagem - `[[item#link-target]]` — alvo do link (`_self` ou `_blank`) - `[[item#link-css-classes]]` — classes CSS extras do link da imagem -
Inglês:
- `[[item#link-url]]` — destination URL of the image link - `[[item#link-target]]` — link target (`_self` or `_blank`) - `[[item#link-css-classes]]` — extra CSS classes of the image link
-
2.2 Módulo de Menus
[MODIFY] menus.php
-
Função
menus_template_options:-
Atualizar a assinatura para receber
$has_custom_code = false:function menus_template_options($selected_id = null, $has_custom_code = false){ -
Dentro do loop
foreach($templates as $template):-
Determinar se o item é o selecionado:
$is_selected = ($selected_id && $template['id'] == $selected_id);. -
A opção original só deve ser marcada como
selectedse$is_selectedfor verdadeiro e$has_custom_codefor falso:$selected_original = ($is_selected && !$has_custom_code) ? ' selected' : '';. -
Caso
$is_selectede$has_custom_codesejam verdadeiros, adicionar também uma opção com o sufixo-modificadomarcada comoselected:$template_id_options .= '<option value="'.$template['id'].'-modificado" selected>'.$template['nome'].' - (Modificado)</option>';
-
-
-
Chamadas à
menus_template_options:-
Na ação de adicionar (linha ~149):
menus_template_options(null, false); -
Na ação de editar (linha ~416):
menus_template_options($fields_schema_decoded['template_id'] ?? null, (!empty($html) || !empty($css))); -
Na ação de clonar (linha ~626):
menus_template_options($fields_schema_decoded['template_id'] ?? null, (!empty($html) || !empty($css)));
-
[MODIFY] menus.js
-
Cache do HTML/CSS de Page Load:
-
No início do escopo do ready, capturar o HTML/CSS dos textareas nativos:
var initialHtml = $('textarea.codemirror-html').val() || ''; var initialCss = $('textarea.codemirror-css').val() || '';
-
-
Seleção do Template no Load:
-
Na inicialização, verificar se a opção
-modificadoexiste antes de selecionar o valor do schema:if (schema.template_id) { var modId = schema.template_id + '-modificado'; var targetId = $('#template_id option[value="' + modId + '"]').length ? modId : schema.template_id; $('#template_id').val(targetId); setTimeout(function () { $('#template_id').dropdown('set selected', targetId); }, 50); }
-
-
Bloqueio de Carga Padrão no Load:
-
Alterar a verificação inicial para não chamar
loadTemplatecaso o template termine em-modificado:var startTid = $template.val(); if (startTid) { if (startTid.endsWith('-modificado')) { // Não sobrescreve o editor, mantém o código carregado do banco. setTimeout(function () { scheduleWidgetPreview(true); }, 600); } else { loadTemplate(startTid); } } else { setTimeout(function () { scheduleWidgetPreview(true); }, 600); }
-
-
Listener do Dropdown de Template:
-
No listener
$template.on('change'), interceptar a seleção de-modificadoe restaurar o cache:$template.on('change', function () { var tid = $(this).val(); toggleTemplateOptionsWrapper(); if (tid) { if (tid.endsWith('-modificado')) { if (typeof window.html_editor_set_html === 'function') window.html_editor_set_html(initialHtml); if (typeof window.html_editor_set_css === 'function') window.html_editor_set_css(initialCss); setTimeout(function () { scheduleWidgetPreview(true, true); }, 150); } else { loadTemplate(tid); } } else { scheduleWidgetPreview(false); } if (typeof window.html_editor_refresh_preview === 'function') { setTimeout(function () { window.html_editor_refresh_preview(); }, 600); } });
-
-
Limpeza no Serializador e Submit:
-
Em
currentSchemaOut(), extrair o ID de template limpo:var tid = $('#template_id').val() || schema.template_id || ''; if (tid.endsWith('-modificado')) { tid = tid.substring(0, tid.length - 11); // remove '-modificado' } out.template_id = tid; -
No evento
.on('submit'), alterar temporariamente o valor do input nativo do select do template para que a gravação direta na colunatemplate_iddo banco seja limpa:var $tempInput = $('#template_id'); var val = $tempInput.val() || ''; if (val.endsWith('-modificado')) { $tempInput.val(val.substring(0, val.length - 11)); } $('input[name="fields_schema"]').val(JSON.stringify(currentSchemaOut())); return true;
-
2.3 Módulo de Galerias
[MODIFY] galleries.php
-
Função
galleries_template_options:-
Atualizar a assinatura para receber
$has_custom_code = false:function galleries_template_options($selected_id = null, $has_custom_code = false){ -
No loop
foreach($templates as $template), adicionar a lógica idêntica de geração de<option value="[id]-modificado">se o template for o selecionado e$has_custom_codefor verdadeiro.
-
-
Chamadas à
galleries_template_options:-
Na ação de adicionar (linha ~234):
galleries_template_options(null, false); -
Na ação de editar (linha ~503):
galleries_template_options($fields_schema_decoded['template_id'] ?? null, (!empty($html) || !empty($css))); -
Na ação de clonar (linha ~714):
galleries_template_options($fields_schema_decoded['template_id'] ?? null, (!empty($html) || !empty($css)));
-
[MODIFY] galleries.js
-
Cache do HTML/CSS de Page Load:
-
Capturar no ready o HTML/CSS inicial dos textareas.
-
-
Seleção do Template no Load:
-
Verificar se
-modificadoexiste antes de selecionarschema.template_id.
-
-
Bloqueio de Carga Padrão no Load:
-
Não chamar
loadTemplatena inicialização se$template.val()terminar em-modificado.
-
-
Listener do Dropdown de Template:
-
Interceptar a seleção de
-modificadopara carregarinitialHtml/initialCssnos editores.
-
-
Limpeza no Serializador e Submit:
-
Limpar o sufixo no
currentSchemaOut()ao definirout.template_id. -
No submit do form, limpar temporariamente a seleção do input
#template_idantes de salvar.
-
2.4 Módulo de Destaques (Publisher Highlights)
[MODIFY] publisher-highlights.php
-
Função
publisher_highlights_template_options:-
Atualizar a assinatura para receber
$has_custom_code = false:function publisher_highlights_template_options($selected_id = null, $has_custom_code = false){ -
No loop
foreach($templates as $template), adicionar a lógica idêntica de geração de<option value="[id]-modificado">se o template for o selecionado e$has_custom_codefor verdadeiro.
-
-
Chamadas à
publisher_highlights_template_options:-
Na ação de adicionar (linha ~173):
publisher_highlights_template_options(null, false); -
Na ação de editar (linha ~455):
publisher_highlights_template_options($fields_schema_decoded['template_id'] ?? null, (!empty($html) || !empty($css))); -
Na ação de clonar (linha ~712):
publisher_highlights_template_options($fields_schema_decoded['template_id'] ?? null, (!empty($html) || !empty($css)));
-
[MODIFY] publisher-highlights.js
-
Cache do HTML/CSS de Page Load:
-
Capturar no ready o HTML/CSS inicial dos textareas:
var initialHtml = $('textarea.codemirror-html').val() || ''; var initialCss = $('textarea.codemirror-css').val() || '';
-
-
Seleção do Template no Load:
-
Verificar se
-modificadoexiste antes de selecionarschema.template_id:if (schema.template_id) { var modId = schema.template_id + '-modificado'; var targetId = $('#template_id option[value="' + modId + '"]').length ? modId : schema.template_id; $('#template_id').val(targetId); setTimeout(function () { $('#template_id').dropdown('set selected', targetId); }, 50); }
-
-
Bloqueio de Carga Padrão no Load:
-
Não chamar
loadTemplatena inicialização se$template.val()terminar em-modificado:var startTid = $template.val(); if (startTid) { if (startTid.endsWith('-modificado')) { setTimeout(function () { scheduleWidgetPreview(true); }, 600); } else { loadTemplate(startTid); } } else { setTimeout(function () { scheduleWidgetPreview(true); }, 600); }
-
-
Listener do Dropdown de Template:
-
No listener
$template.on('change'), interceptar a seleção de-modificadopara carregarinitialHtml/initialCssnos editores.
-
-
Limpeza no Submit:
-
Na interceptação do envio (submit):
var $tempInput = $('#template_id'); var val = $tempInput.val() || ''; if (val.endsWith('-modificado')) { $tempInput.val(val.substring(0, val.length - 11)); } var tid = $('#template_id').val() || ''; if (tid.endsWith('-modificado')) { tid = tid.substring(0, tid.length - 11); } schema.template_id = tid;
-
3. Plano de Verificação
3.1 Testes Automatizados (Estáticos)
-
Verificar sintaxe dos arquivos alterados:
-
node --check gestor/modulos/menus/menus.js -
node --check gestor/modulos/galleries/galleries.js -
node --check gestor/modulos/publisher-highlights/publisher-highlights.js -
php -l gestor/modulos/menus/menus.php -
php -l gestor/modulos/galleries/galleries.php -
php -l gestor/modulos/publisher-highlights/publisher-highlights.php
-
3.2 Verificação Manual
-
Edição sem Sobrescrita:
-
Criar um menu, galeria ou destaque; selecionar um template padrão, alterar um elemento do HTML e salvar.
-
Entrar na tela de edição do registro novamente: o dropdown de Modelo deve mostrar
[Nome do Modelo] - (Modificado). O editor HTML deve preservar a alteração e não ser sobrescrito.
-
-
Troca de Modelos:
-
Na tela de edição, mudar o select para a opção do modelo original. O AJAX deve carregar a versão limpa do template.
-
Mudar de volta para a opção com
- (Modificado). O editor deve restaurar o código alterado inicial.
-
-
Clonagem de Registro:
-
Clicar no botão clonar de um registro modificado. Na tela de clonagem, confirmar que a opção
- (Modificado)está selecionada e que o editor exibe o HTML alterado.
-
-
Persistência Limpa no Banco:
-
Salvar o registro modificado ou o clone. Inspecionar o banco de dados e confirmar que o
template_idfoi salvo de forma limpa (sem o sufixo-modificado).
-
-
Validação dos Prompts de IA:
-
Verificar que a IA de destaques e galerias segue as novas instruções do bloco vazio e das tags de âncora de links individuais.
-