Conn2Flow
Navegação das docs

SDD

req-050: Escape HTML, Correção de Abas Aninhadas e Novos Modelos no Módulo Formulários (Forms)

Este lote de trabalho (BATCH-050) define correções no comportamento do editor HTML e abas do módulo Forms, e adiciona 4 novos templates de formulários estilizados via Tailwind CSS…

Este lote de trabalho (BATCH-050) define correções no comportamento do editor HTML e abas do módulo Forms, e adiciona 4 novos templates de formulários estilizados via Tailwind CSS (totalizando 8 arquivos traduzidos).


1. Modificações no html-editor e forms (Escape HTML)

1.1 Modificar gestor/bibliotecas/html-editor.php

  • Localizar a assinatura da função html_editor_componente($params = false).

  • Adicionar suporte ao parâmetro 'html_specialchars' (booleano) via $params.

  • Se html_specialchars for true, realizar o escape dos placeholders #pagina-html# e #pagina-html-extra-head# diretamente no $html_editor antes de retorná-lo.

  • Implementação recomendada:

    if (isset($html_specialchars) && $html_specialchars) {
        $html_val = isset($html) ? $html : '';
        $html_extra_head_val = isset($html_extra_head) ? $html_extra_head : '';
        $html_editor = modelo_var_troca_tudo($html_editor, '#pagina-html#', htmlspecialchars($html_val, ENT_QUOTES, 'UTF-8'));
        $html_editor = modelo_var_troca_tudo($html_editor, '#pagina-html-extra-head#', htmlspecialchars($html_extra_head_val, ENT_QUOTES, 'UTF-8'));
    }

1.2 Modificar gestor/modulos/forms/forms.php

  • Localizar a função forms_prepare_editor_page.

  • Atualizar a chamada html_editor_componente($params) para incluir 'html_specialchars' => true e passar $html e $html_extra_head no array $params:

    $params = [
        'modulo' => $modulo,
        'alvo' => 'forms',
        'alvos_modelos' => 'forms',
        'target_variables' => forms_item_variables(),
        'html_specialchars' => true,
        'html' => $html,
        'html_extra_head' => $html_extra_head,
    ];
    $params[$modo] = true;

2. Correção de Colisão nas Abas Aninhadas (Tabs Bug)

2.1 Modificar gestor/modulos/forms/forms.js

  • Isolar o contexto de inicialização dos menus de abas Fomantic UI na tela de adição/edição para evitar que a aba principal perca o foco e suma ao alternar sub-abas.

  • Alterar as configurações de tab na inicialização (linhas ~18 e ~25):

    $('.menuForms .item').tab({
        context: 'parent',
        onLoad: function (tabPath) {
            localStorage.setItem(gestor.moduloId + 'formsActiveTab', tabPath);
            if (tabPath === 'forms-template') schedulePreview(true, true);
        }
    });
    $('.menuFormsTemplate .item').tab({
        context: '[data-tab="forms-template"]',
        onLoad: function (tabPath) {
            if (tabPath === 'forms-preview') schedulePreview(true, true);
            if (tabPath === 'forms-editor' && typeof window.contentPageTabHandler === 'function') window.contentPageTabHandler();
            if (tabPath === 'forms-widget') updateWidgetCodeTab();
        }
    });

3. Criação de Novos Modelos de Formulários (Tailwind CSS)

3.1 Criar Ficheiros Físicos dos Templates

Criar as seguintes pastas e arquivos de templates. Todos devem usar Tailwind CSS e manter a estrutura de loop (<!-- item < --> ... <!-- item > -->) com as condicionais de tipo de input:

3.1.1 Inscrição na Newsletter (forms-newsletter-newsletter)

  • PT-BR: gestor/modulos/forms/resources/pt-br/templates/forms-newsletter-newsletter/forms-newsletter-newsletter.html

    <form class="conn2flow-form bg-white border border-gray-200 rounded-xl shadow-sm p-6 max-w-md mx-auto space-y-4" data-form-id="@[[form_id]]@" method="post">
    <input type="hidden" name="form_id" value="@[[form_id]]@">
    <div class="text-center pb-2">
        <h3 class="text-lg font-bold text-gray-800">Fique por dentro!</h3>
        <p class="text-xs text-gray-500">Receba novidades e conteúdos exclusivos diretamente no seu e-mail.</p>
    </div>
    <!-- item < -->
    <div class="conn2flow-form-field">
        <label class="block text-xs font-semibold text-gray-600 mb-1" for="@[[form_id]]@-@[[item#name]]@">@[[item#label]]@</label>
        <!-- type-input < -->
        <input class="w-full text-sm rounded-lg border border-gray-300 px-3 py-2.5 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition" type="@[[item#type]]@" id="@[[form_id]]@-@[[item#name]]@" name="@[[item#name]]@" placeholder="@[[item#placeholder]]@" @[[item#required]]@>
        <!-- type-input > -->
        <!-- type-textarea < -->
        <textarea class="w-full text-sm rounded-lg border border-gray-300 px-3 py-2.5 min-h-24 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition" id="@[[form_id]]@-@[[item#name]]@" name="@[[item#name]]@" placeholder="@[[item#placeholder]]@" @[[item#required]]@></textarea>
        <!-- type-textarea > -->
        <!-- type-select < -->
        <select class="w-full text-sm rounded-lg border border-gray-300 px-3 py-2.5 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition bg-white" id="@[[form_id]]@-@[[item#name]]@" name="@[[item#name]]@" @[[item#required]]@>
            @[[item#options]]@
        </select>
        <!-- type-select > -->
    </div>
    <!-- item > -->
    <div class="conn2flow-form-message hidden text-sm p-3 rounded-lg"></div>
    <button class="w-full py-2.5 px-4 bg-blue-600 hover:bg-blue-700 text-white font-medium text-sm rounded-lg shadow-sm hover:shadow transition duration-150 conn2flow-form-submit" type="submit">Inscrever-se</button>
    </form>
  • EN: gestor/modulos/forms/resources/en/templates/forms-newsletter-newsletter/forms-newsletter-newsletter.html (Mesmo HTML, traduzindo "Fique por dentro!" para "Stay Updated!", o subtítulo para "Get the latest news and updates delivered straight to your inbox." e "Inscrever-se" para "Subscribe")

3.1.2 Registro de Usuário (forms-registro-usuario)

  • PT-BR: gestor/modulos/forms/resources/pt-br/templates/forms-registro-usuario/forms-registro-usuario.html

    <form class="conn2flow-form bg-white border border-gray-200 rounded-2xl shadow-md p-8 max-w-xl mx-auto space-y-5" data-form-id="@[[form_id]]@" method="post">
    <input type="hidden" name="form_id" value="@[[form_id]]@">
    <div class="border-b border-gray-100 pb-4">
        <h2 class="text-xl font-bold text-gray-800">Criar Nova Conta</h2>
        <p class="text-sm text-gray-500">Preencha os campos abaixo para iniciar o seu cadastro.</p>
    </div>
    <!-- item < -->
    <div class="conn2flow-form-field">
        <label class="block text-sm font-medium text-gray-700 mb-1.5" for="@[[form_id]]@-@[[item#name]]@">@[[item#label]]@</label>
        <!-- type-input < -->
        <input class="w-full text-sm rounded-lg border border-gray-300 px-3.5 py-2.5 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition" type="@[[item#type]]@" id="@[[form_id]]@-@[[item#name]]@" name="@[[item#name]]@" placeholder="@[[item#placeholder]]@" @[[item#required]]@>
        <!-- type-input > -->
        <!-- type-textarea < -->
        <textarea class="w-full text-sm rounded-lg border border-gray-300 px-3.5 py-2.5 min-h-28 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition" id="@[[form_id]]@-@[[item#name]]@" name="@[[item#name]]@" placeholder="@[[item#placeholder]]@" @[[item#required]]@></textarea>
        <!-- type-textarea > -->
        <!-- type-select < -->
        <select class="w-full text-sm rounded-lg border border-gray-300 px-3.5 py-2.5 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent transition bg-white" id="@[[form_id]]@-@[[item#name]]@" name="@[[item#name]]@" @[[item#required]]@>
            @[[item#options]]@
        </select>
        <!-- type-select > -->
    </div>
    <!-- item > -->
    <div class="conn2flow-form-message hidden text-sm p-3 rounded-lg"></div>
    <button class="w-full py-3 px-4 bg-indigo-600 hover:bg-indigo-700 text-white font-semibold text-sm rounded-lg shadow-md hover:shadow-lg transition duration-200 conn2flow-form-submit" type="submit">Cadastrar</button>
    </form>
  • EN: gestor/modulos/forms/resources/en/templates/forms-registro-usuario/forms-registro-usuario.html (Mesmo HTML, traduzindo "Criar Nova Conta" para "Create Account", "Preencha os campos abaixo..." para "Fill in the details below to register your account." e "Cadastrar" para "Register")

3.1.3 Pesquisa de Satisfação (forms-pesquisa-satisfacao)

  • PT-BR: gestor/modulos/forms/resources/pt-br/templates/forms-pesquisa-satisfacao/forms-pesquisa-satisfacao.html

    <form class="conn2flow-form bg-slate-50 border border-slate-200 rounded-xl p-6 max-w-2xl mx-auto space-y-4" data-form-id="@[[form_id]]@" method="post">
    <input type="hidden" name="form_id" value="@[[form_id]]@">
    <div class="text-left border-b border-slate-200 pb-3">
        <h3 class="text-lg font-bold text-slate-800">Sua opinião é importante!</h3>
        <p class="text-xs text-slate-500">Ajude-nos a melhorar nossos serviços deixando o seu feedback.</p>
    </div>
    <!-- item < -->
    <div class="conn2flow-form-field">
        <label class="block text-xs font-bold text-slate-700 uppercase tracking-wider mb-1" for="@[[form_id]]@-@[[item#name]]@">@[[item#label]]@</label>
        <!-- type-input < -->
        <input class="w-full text-sm rounded-md border border-slate-300 px-3 py-2 bg-white focus:outline-none focus:border-slate-500 transition" type="@[[item#type]]@" id="@[[form_id]]@-@[[item#name]]@" name="@[[item#name]]@" placeholder="@[[item#placeholder]]@" @[[item#required]]@>
        <!-- type-input > -->
        <!-- type-textarea < -->
        <textarea class="w-full text-sm rounded-md border border-slate-300 px-3 py-2 bg-white min-h-24 focus:outline-none focus:border-slate-500 transition" id="@[[form_id]]@-@[[item#name]]@" name="@[[item#name]]@" placeholder="@[[item#placeholder]]@" @[[item#required]]@></textarea>
        <!-- type-textarea > -->
        <!-- type-select < -->
        <select class="w-full text-sm rounded-md border border-slate-300 px-3 py-2 bg-white focus:outline-none focus:border-slate-500 transition" id="@[[form_id]]@-@[[item#name]]@" name="@[[item#name]]@" @[[item#required]]@>
            @[[item#options]]@
        </select>
        <!-- type-select > -->
    </div>
    <!-- item > -->
    <div class="conn2flow-form-message hidden text-sm p-3 rounded-lg"></div>
    <button class="w-full py-2.5 px-4 bg-slate-800 hover:bg-slate-900 text-white font-bold text-sm rounded-md shadow-sm transition duration-150 conn2flow-form-submit" type="submit">Enviar Avaliação</button>
    </form>
  • EN: gestor/modulos/forms/resources/en/templates/forms-pesquisa-satisfacao/forms-pesquisa-satisfacao.html (Mesmo HTML, traduzindo "Sua opinião é importante!" para "We Value Your Feedback", o subtítulo para "Help us improve our services by sharing your experience." e "Enviar Avaliação" para "Submit Feedback")

3.1.4 Suporte Técnico (forms-suporte-tecnico)

  • PT-BR: gestor/modulos/forms/resources/pt-br/templates/forms-suporte-tecnico/forms-suporte-tecnico.html

    <form class="conn2flow-form bg-white border-t-4 border-t-emerald-500 border-x border-b border-gray-200 rounded-b-xl rounded-t-sm shadow p-6 max-w-2xl mx-auto space-y-4" data-form-id="@[[form_id]]@" method="post">
    <input type="hidden" name="form_id" value="@[[form_id]]@">
    <div class="pb-2 border-b border-gray-100">
        <h3 class="text-lg font-bold text-gray-800">Nova Solicitação de Suporte</h3>
        <p class="text-xs text-gray-500">Abra um chamado técnico e nossa equipe responderá o mais rápido possível.</p>
    </div>
    <!-- item < -->
    <div class="conn2flow-form-field">
        <label class="block text-sm font-semibold text-gray-700 mb-1" for="@[[form_id]]@-@[[item#name]]@">@[[item#label]]@</label>
        <!-- type-input < -->
        <input class="w-full text-sm rounded border border-gray-300 px-3 py-2 focus:outline-none focus:border-emerald-500 transition" type="@[[item#type]]@" id="@[[form_id]]@-@[[item#name]]@" name="@[[item#name]]@" placeholder="@[[item#placeholder]]@" @[[item#required]]@>
        <!-- type-input > -->
        <!-- type-textarea < -->
        <textarea class="w-full text-sm rounded border border-gray-300 px-3 py-2 min-h-32 focus:outline-none focus:border-emerald-500 transition" id="@[[form_id]]@-@[[item#name]]@" name="@[[item#name]]@" placeholder="@[[item#placeholder]]@" @[[item#required]]@></textarea>
        <!-- type-textarea > -->
        <!-- type-select < -->
        <select class="w-full text-sm rounded border border-gray-300 px-3 py-2 bg-white focus:outline-none focus:border-emerald-500 transition" id="@[[form_id]]@-@[[item#name]]@" name="@[[item#name]]@" @[[item#required]]@>
            @[[item#options]]@
        </select>
        <!-- type-select > -->
    </div>
    <!-- item > -->
    <div class="conn2flow-form-message hidden text-sm p-3 rounded-lg"></div>
    <button class="w-full py-2.5 px-4 bg-emerald-600 hover:bg-emerald-700 text-white font-semibold text-sm rounded shadow hover:shadow-md transition duration-150 conn2flow-form-submit" type="submit">Enviar Chamado</button>
    </form>
  • EN: gestor/modulos/forms/resources/en/templates/forms-suporte-tecnico/forms-suporte-tecnico.html (Mesmo HTML, traduzindo "Nova Solicitação de Suporte" para "New Support Request", o subtítulo para "Open a technical support ticket and our team will reply as soon as possible." e "Enviar Chamado" para "Submit Request")

3.2 Atualizar gestor/modulos/forms/forms.json

Registrar os novos modelos criados no array templates de ambos os blocos pt-br e en, definindo a versão inicial como "1.0" e checksums vazios:

  • pt-br:

                {
                    "name": "Inscrição na Newsletter",
                    "id": "forms-newsletter-newsletter",
                    "target": "forms",
                    "framework_css": "tailwindcss",
                    "version": "1.0",
                    "checksum": {
                        "html": "",
                        "css": "",
                        "combined": ""
                    }
                },
                {
                    "name": "Registro de Usuário",
                    "id": "forms-registro-usuario",
                    "target": "forms",
                    "framework_css": "tailwindcss",
                    "version": "1.0",
                    "checksum": {
                        "html": "",
                        "css": "",
                        "combined": ""
                    }
                },
                {
                    "name": "Pesquisa de Satisfação",
                    "id": "forms-pesquisa-satisfacao",
                    "target": "forms",
                    "framework_css": "tailwindcss",
                    "version": "1.0",
                    "checksum": {
                        "html": "",
                        "css": "",
                        "combined": ""
                    }
                },
                {
                    "name": "Suporte Técnico",
                    "id": "forms-suporte-tecnico",
                    "target": "forms",
                    "framework_css": "tailwindcss",
                    "version": "1.0",
                    "checksum": {
                        "html": "",
                        "css": "",
                        "combined": ""
                    }
                }
  • en:

                {
                    "name": "Newsletter Subscription",
                    "id": "forms-newsletter-newsletter",
                    "target": "forms",
                    "framework_css": "tailwindcss",
                    "version": "1.0",
                    "checksum": {
                        "html": "",
                        "css": "",
                        "combined": ""
                    }
                },
                {
                    "name": "User Registration",
                    "id": "forms-registro-usuario",
                    "target": "forms",
                    "framework_css": "tailwindcss",
                    "version": "1.0",
                    "checksum": {
                        "html": "",
                        "css": "",
                        "combined": ""
                    }
                },
                {
                    "name": "Satisfaction Survey",
                    "id": "forms-pesquisa-satisfacao",
                    "target": "forms",
                    "framework_css": "tailwindcss",
                    "version": "1.0",
                    "checksum": {
                        "html": "",
                        "css": "",
                        "combined": ""
                    }
                },
                {
                    "name": "Technical Support",
                    "id": "forms-suporte-tecnico",
                    "target": "forms",
                    "framework_css": "tailwindcss",
                    "version": "1.0",
                    "checksum": {
                        "html": "",
                        "css": "",
                        "combined": ""
                    }
                }

3.3 Rodar Compilador de Recursos

Após criar os arquivos físicos e registrar as opções de template no forms.json, execute o script do compilador local para preencher os hashes checksums correspondentes e regenerar o banco:

  • Comando: php ./gestor/controladores/agents/arquitetura/atualizacao-dados-recursos.php


4. Verificação de Funcionamento (Tests & Check)

4.1 Testes Automatizados

  • Rodar a suíte inteira de testes locais para confirmar integridade:

    • Comando: composer test

    • Comando: npm run test

O Futuro é Híbrido: Humano + IA.

O Conn2Flow é a ferramenta. Se você precisa do Arquiteto para desenhar a estratégia da sua empresa usando essa tecnologia...

Contrate Consultoria Especializada