Novo Sistema de Temas no LS3.x
From LimeSurvey Manual
Introdução
Atenção: nas versões anteriores do LimeSurvey, os arquivos que definem a aparência do questionário e como ele é apresentado em termos de cores, fontes, layout e (algum) comportamento eram chamados de "modelo". Devido a novas percepções, isso agora é chamado de "tema", enquanto "modelo" é reservado para questionários de exemplo.
Nesta página, você aprenderá a:
- Usar o novo sistema de temas do LimeSurvey 3.0.
- Usar a herança para gerenciar seus próprios temas.
- Adicionar uma imagem ao seu tema
- Gerenciar as opções de tema para seus questionários e grupos de questionários
O LimeSurvey 3 introduz um novo sistema completo de mecanismo de temas, baseado em Twig 1.29 e Bootstrap, que permite a herança de temas e as opções de tema. Ele remove completamente o antigo sistema de palavras-chave de substituição. Assim, agora 100% do HTML do frontend pode ser personalizado. Por exemplo, no antigo sistema de temas, havia uma palavra-chave {ASSESSMENTS} que era substituída pelo HTML da avaliação em tempo de execução. Um designer de temas não tinha como personalizar esse HTML (a não ser usando JavaScript). Agora, há um arquivo chamado assessments.twig que contém a lógica (escrita em Twig) para gerar esse HTML. Nestas páginas, daremos algumas explicações sobre como usar esse novo mecanismo de temas.
Edição usando a interface de administração
Lista de temas
No painel de administração, agora há uma caixa para acessar a lista de temas:

A lista é dividida em 5 colunas:
- uma prévia do tema: é apenas um arquivo de imagem chamado "preview.png" na raiz do tema
- o "título" do tema, conforme especificado no manifesto (config.xml na raiz do tema)
- a descrição do tema: um texto definido em seu manifesto
- o tipo de tema: Tema central (fornecido com o LimeSurvey), Tema do usuário (adicionado no diretório de carregamento), Tema XML (não carregado no banco de dados)
- Estender: se o tema estende outro tema, o nome dele será indicado aqui
- Alguns botões de ação:
- Instalar: carrega o manifesto de um tema para adicioná-lo ao banco de dados e torná-lo disponível para seleção no nível do questionário
- Desinstalar: exclui as entradas de configuração de um tema no banco de dados
- Editor de temas: redireciona você para o editor de temas
- Opções de tema: leva você à configuração global das opções de tema
Editor de temas
O Editor de temas foi mantido o mais próximo possível do original. Assim, ao abrir um tema central, você não pode editá-lo. Mas agora, em vez de um botão "copiar", você tem um botão "estender".

Uma visão geral rápida do conceito de herança de temas
No LS3, um tema agora pode herdar de outro tema, ou seja, pode "estender" outro tema. Isso significa que o diretório do tema ficará praticamente vazio e conterá apenas os arquivos (views, folhas de estilo, scripts, recursos etc.) que diferem dos originais. Dessa forma, será fácil criar uma frota de temas para seus diferentes usuários sem precisar manter vários temas diferentes. Por exemplo: você pode ter seu próprio tema caseiro e, depois, uma versão para uma empresa (com seu logotipo, seu estilo, talvez um link para o site dela no rodapé etc.), outra versão para outra empresa etc. Se você então atualizar o CSS ou o layout global do seu tema personalizado, todos os temas que herdam dele serão atualizados automaticamente. Observe que a herança é recursiva: um tema pode estender um tema que estende outro, e assim por diante.
Novidades na interface do usuário
Para estender o tema Monochrome do LimeSurvey, acesse a lista de temas e clique no botão "Editor de temas" do tema Monochrome. Em seguida, clique em "Estender" e confirme o novo nome "extends_monochrome".
Se agora você for ao diretório de carregamento (upload) com seu cliente de arquivos/FTP, verá que um novo diretório foi criado: upload/themes/extends_monochrome Ele contém um arquivo XML e diretórios, mas a maioria dos diretórios está vazia. Ele não tem views, nem CSS, nem JS. Mesmo assim, você ainda pode selecionar esse tema como um tema normal em um questionário e ele terá exatamente a mesma aparência do tema monochrome.

O editor de temas para o tema extends_monochrome é assim:

Não há grande diferença em relação ao antigo editor de temas. Vamos listar as principais:
- A palavra-chave Herdado na lista de arquivos. Ela significa que o arquivo não está presente no diretório do tema e que o arquivo do tema original será usado.

- O editor principal ( Editor ACE ) mostra o conteúdo do arquivo selecionado. Os arquivos não contêm apenas HTML, CSS ou JS, mas também instruções Twig. Essas instruções Twig nos dão a possibilidade de levar alguma lógica para views do tema que antes ficavam no fundo do núcleo e que agora podem ser personalizadas.

- É por isso que agora você tem mais tipos de tela disponíveis no seletor suspenso do menu superior. Você notará páginas como "Lista de questionários", "Carregar", "Salvar", "Erro", "Registro", "Avaliações" e "Imprimir respostas", que não estavam disponíveis antes ou que não podiam ser realmente personalizadas.

- O link "Dica" na parte inferior da lista de arquivos mostra a maneira de adicionar uma imagem ao seu HTML usando Twig

- O botão "Salvar alterações" se torna um botão Copie para o tema local e salve as alterações

Exemplo rápido: adicionando uma imagem
O botão Copie para o tema local e salve as alterações faz exatamente o que diz: se você editar qualquer coisa dentro do arquivo e clicar nesse botão, ele copiará o arquivo para o tema que você está editando e salvará suas alterações.
Por exemplo: clique no arquivo layout_global.twig e, logo antes do bloco content ( {% block content %}), adicione o texto "TEST" e clique no botão. Você pode ver que o rótulo do arquivo mudou de "Herdado" para "local" e agora o botão é um simples botão Salvar alterações.

Se você abrir um explorador de arquivos e for ao diretório upload/themes/extends_monochrome/views/, verá que ele contém apenas um arquivo, o layout_global.twig, e que o texto "TEST" está lá.

Agora, em vez de adicionar um texto aleatório, vamos adicionar uma imagem. Se você clicar no link Dica, ele dirá:
Para usar uma imagem em um arquivo .twig:
{{ image('./files/myfile.png', 'alt-text for my file', {"class": "myclass"}) }}
Se você leu a documentação do Twig (e já deveria tê-lo feito a esta altura), sabe que {{ function( ) }} exibirá na tela o resultado de uma função. Aqui, a função é image( ).
Se você não entender o código, não se preocupe: você não precisa saber como ela funciona, mas por que e como usá-la.
Você deve usar a função image() por dois motivos:
- A função image percorre o tema para encontrar a imagem. Se o tema em que você está trabalhando estende outro tema, e se você copiar localmente o arquivo onde inseriu a imagem, mas essa imagem não for copiada para o tema local, ela percorrerá a árvore de herança do tema para encontrar onde a imagem está.
- Ela usará o gerenciador de assets, o que melhorará o desempenho do seu tema. Consulte a documentação do Yii Asset Manager para mais informações: http://www.yiiframework.com/wiki/148/understanding-assets/
Portanto, para adicionar uma imagem ao seu tema:
- basta fazer o carregamento dela normalmente com o carregador de arquivos à direita e depois adicioná-la onde desejar em qualquer arquivo twig:
{{ image('./files/myfile.png') }}
- Se você quiser adicionar um texto alternativo para a imagem (para leitores de tela e validação de HTML), adicione:
{{ image('./files/myfile.png'), ‘my alternative text’ }}
- Se você quiser adicionar um atributo de classe e um id:
{{ image('./files/myfile.png'), ‘my alternative text’, {“class”: “a_nice_css_class”, “id”: “any_id”} }}
Algumas coisas em nossa lista de tarefas
- Dar aos usuários a possibilidade de fazer o carregamento de um arquivo de prévia personalizado a partir do próprio editor
- Adicionar um botão para excluir o arquivo local e voltar ao estado herdado
- Copiar apenas a imagem usada nos arquivos CSS (listando-as no manifesto como arquivos a copiar)
- Lembrar qual tema o atual estende (se houver)
Opções de tema
Outra novidade do LS3 é a página de opções de tema. Como veremos mais adiante, os criadores de temas podem criar suas próprias opções e até sua própria página de opções de administração. Aqui, veremos rapidamente como funciona a página de opções dos temas centrais. Para acessar as opções de tema no nível global: clique em "Opções de tema" na lista de temas
Opções avançadas
Ao abrir a guia Opções de tema, você pode optar por editar as Opções simples ou as Opções avançadas. “Opções avançadas” é apenas um formulário simples que dá acesso aos principais campos de configuração do tema no banco de dados. Para entender como funciona, você também deve ler sobre o arquivo XML e a criação de um tema do zero. Portanto, é um recurso bastante complexo e feito para usuários avançados.
No entanto, se você deseja editar as configurações avançadas, clique na guia Opções avançadas

- Arquivos CSS: Os arquivos CSS que devem ser adicionados ao tema;
- Arquivos JS: Os arquivos JS que devem ser adicionados ao tema;
- Arquivos de impressão CSS: Os arquivos CSS a serem carregados ao imprimir um tema;
- Opções: Este campo inclui as opções (e seus valores) que devem ser processadas na visualização do tema;
- CssFramework Name: O nome do framework CSS a ser carregado. Por enquanto, apenas Bootstrap ou nenhum;
- Cssframework Css: Neste campo, você pode substituir o bootstrap.css principal por uma versão personalizada diferente dele;
- Cssframework Js: O campo do boostrap.js principal pode ser substituído aqui por uma versão personalizada diferente dele;
- Pacotes para carregar: Com esta configuração, você pode carregar alguns pacotes de recursos principais do LimeSurvey.
Você notará um campo de carregamento no topo, que permite fazer o carregamento de um arquivo para o diretório de arquivos do tema. Esses parâmetros podem ser usados para alterar toda a aparência do tema.
Opções simples
A página de opções simples vem do próprio tema. Ela é feita por meio de um arquivo twig e algum JavaScript dentro do diretório /options do tema: https://github.com/LimeSurvey/LimeSurvey/tree/develop/templates/default/options (Link quebrado)

A página de opções simples apenas preenche os campos do formulário avançado. Você pode ver isso ativando ou desativando uma configuração na página simples e observando como o campo correspondente no formulário avançado é modificado. Por exemplo, nas opções simples do tema padrão, se você mudar o tema Bootswatch para "Darkly" e depois clicar na aba de opções avançadas (mesmo sem salvar), verá que o campo "Cssframework Css" mudou de
{"replace": [["css/bootstrap.css","css/flatly.css"]]}
para
{"replace": [["css/bootstrap.css","css/darkly.css"]]}
Aqui estão as diferentes opções simples dos temas principais:
- Ajax mode: define se a próxima página deve ser carregada via ajax (mais rápido) ou por recarregamento da página (melhor para fins de depuração)
- Imagem de fundo: se definido como Sim, a imagem chamada pattern.png será carregada (será substituída por um seletor de arquivos no Master)
- Box container: se definido como Não, as perguntas não ficarão contidas em uma caixa (assim você pode usar matrizes grandes, maiores que a largura da tela)
- Brandlogo: se definido como não, o nome do questionário será exibido na barra superior; caso contrário, você pode selecionar uma das imagens do diretório de arquivos para ser usada como logotipo.
- Animar corpo: se definido como sim, você pode escolher uma das animações a serem aplicadas quando o corpo do questionário for carregado
- Animar pergunta: o mesmo para as perguntas
- Animate alerts: o mesmo para os alertas
- Bootstrap theme: aqui você pode escolher um tema Bootstrap para carregar. Eles vêm do Bootswatch https://bootswatch.com/3/
A biblioteca usada para as animações é a animate.css: https://daneden.github.io/animate.css/
É claro que um fornecedor de temas pode adicionar a sua própria biblioteca de animação ou nenhuma biblioteca de animação.
Sistema de herança
Na parte anterior, vimos que um tema pode expandir outro tema. A configuração de um tema também pode herdar de outra configuração de tema. Isso significa que, para um determinado tema, você pode ter uma configuração em
- nível global (aquele que acabamos de ver, acessível a partir da lista de temas)
- nível de grupo de questionários
- e, por último, nível de questionário.
Cada parâmetro em um determinado nível pode herdar do nível superior: herança do grupo de questionários. Primeiro, vamos ver o nível de grupo de questionários.
No nível de grupo de questionários
Na verdade, uma das outras grandes novidades do LS3 é o sistema de grupos de questionários. Agora você pode criar diferentes grupos para organizar seus questionários. Para acessá-lo, vá até a lista de questionários e clique na aba de grupos de questionários:

Nesta lista, você tem dois botões de ação. Se o grupo estiver vazio, você pode excluí-lo. Caso contrário, você sempre pode editá-lo. Ao clicar no botão de edição, você chega à página de configuração do grupo de questionários:

A terceira aba desta página chama-se “Template options for this survey group”. Se você clicar nela, verá a mesma lista de temas da lista de temas, exceto que aqui apenas o botão de opções está visível (o editor de temas só pode ser acessado a partir da lista principal).
Agora, se você clicar na opção do tema padrão (Default Template), verá isto:

- Herdar tudo significa que toda a configuração será herdada do nível de configuração global.
- Se você for à página de opções avançadas, verá que todos os campos estão definidos como herdar.
- Se você clicar em "Não" em "Herdar tudo" nas opções simples, verá novamente uma página muito semelhante à página de opções global. A única diferença é que, para cada campo, você pode definir sim, não ou herdar; e cada seletor suspenso tem um valor herdar'.

No nível de questionário
Ao editar um questionário, no menu da barra lateral esquerda, você verá uma nova entrada “Opções de tema”. Ela o levará à página de opções do tema selecionado para o questionário atual. Você encontrará o mesmo sistema de herança do grupo de questionários, mas desta vez, herdar significa que a configuração será herdada do grupo de questionários do questionário.

Exemplo de caso de uso
Digamos que você use um único tema para diferentes empresas (A e B). Você define suas opções favoritas no nível global (por exemplo: ajax ligado, animação do corpo com slide in, alertas com pulse). Em seguida, você cria um grupo de questionários para cada empresa: um grupo de questionários para a empresa A, que hospedará todos os questionários dessa empresa, e um para a empresa B, que hospedará todos os questionários da empresa B. Nesse nível, você definirá apenas o logotipo e o fundo, e deixará as outras opções herdarem. Assim, todos os questionários do grupo A usarão o logotipo da empresa A, e todos os do grupo B o logotipo da empresa B. Para um dos questionários da empresa A, você poderia usar um fundo diferente, relacionado ao tema do questionário: basta alterar o fundo nas opções no nível de questionário. Se alguém da empresa B disser que o alerta pulsante é agressivo demais e que preferiria algo mais suave, como um fade in, basta alterar a animação de alerta no nível do grupo de questionários B e todos os questionários desse grupo passarão a usar essa animação. Se a empresa A mudar o seu logotipo, você pode alterá-lo no nível do grupo de questionários A, e todos os questionários desse grupo usarão o novo logotipo.
Perguntas frequentes sobre a personalização de temas
Aqui você encontrará algumas respostas a perguntas feitas no fórum que podem ajudá-lo a personalizar o seu tema.
Personalizando CSS/JS: lidando com o gerenciador de assets ("por que minhas alterações não são aplicadas?")
Se você tentar atualizar o CSS/JS de um tema editando diretamente o código com o seu editor favorito, pode se surpreender ao ver que as suas alterações não são aplicadas.
Desde a versão 2.50, o LS usa o gerenciador de assets do Yii:
Documentação do Yii sobre Assets
Ele move os arquivos CSS/JS de um tema para um subdiretório tmp/ com uma sequência aleatória (por exemplo: "tmp/1ef64ml/"). Assim, se você fizer qualquer alteração em um arquivo css/js e informar o gerenciador de assets, os arquivos são copiados para um novo subdiretório com um novo nome, de modo que o cache do navegador do usuário seja atualizado e ele veja o novo css/js. Caso contrário, ele teria de limpar o cache do navegador.
Aqui estão os links CSS no cabeçalho quando o gerenciador de assets está ativado:
Como você pode ver, todos se referem aos subdiretórios tmp/.
Aqui estão os links CSS no cabeçalho quando o gerenciador de assets está desativado:
Como você pode ver, eles apontam para os arquivos reais do tema.
Portanto, ao editar o CSS/JS de um tema, você tem várias possibilidades:
- Você pode usar o Editor de temas do LS: ele lida com o gerenciador de assets e você não precisa se preocupar com nada
- Você pode ativar o modo de depuração: ele desativa o gerenciador de assets, de modo que os arquivos css/js reais dos seus temas são chamados (mas, nesse caso, você tem de atualizar o cache do navegador a cada carregamento)
- Você pode atualizar o cache de assets: em Definições globais -> General -> Clear asset cache
Usar o editor de temas ajudará você a entender a arquitetura do novo motor de temas.
Além disso, se você estiver personalizando o fruity, tenha cuidado com a especificidade do CSS: a maioria das definições usa o seletor ".fruity" (uma das classes do elemento body).
Adicionando fontes personalizadas ao meu tema
O jeito fácil: usando o Google Font CDN
O tema de questionário Bootswatch usa o Google Font CDN. Vamos ver como ele funciona: https://github.com/LimeSurvey/LimeSurvey/blob/70a1d99cd2ebe411597231a8bc746b4ca9e19584/themes/survey/bootswatch/css/variations/flatly.min.css
@import url("https://fonts.googleapis.com/css?family=Lato:400,700,400italic");
Em seguida, a fonte Lato é usada por meio de regras CSS: https://github.com/thomaspark/bootswatch/blob/master/dist/flatly/bootstrap.css#L72
body {
...
font-family: "Lato";
...
}
Você pode usar qualquer fonte do Google dessa forma em seu tema personalizado. Naturalmente, você deve remover o seletor de fonte das opções do seu tema. Exclua estas linhas em options.twig: https://github.com/LimeSurvey/LimeSurvey/blob/70a1d99cd2ebe411597231a8bc746b4ca9e19584/themes/survey/vanilla/options/options.twig#L209-L230
Usando fonte local
É claro que você também pode baixar os arquivos de fonte e usá-los a partir do servidor local em vez do CDN do Google (melhor para a privacidade). Para ter um exemplo de como fazer isso, veja nossa versão local da fonte Noto: https://github.com/LimeSurvey/LimeSurvey/blob/70a1d99cd2ebe411597231a8bc746b4ca9e19584/assets/fonts/noto.css
@font-face {
font-family: 'Noto Sans';
font-weight: 300;
font-style: normal;
src: url('./font-src/Noto/NotoSans-Regular.ttf');
}
...
Você pode usar uma definição muito semelhante no arquivo CSS do seu tema e, em seguida, copiar o arquivo NotoSans-Regular.ttf para a pasta css/font-src/ do seu tema.
Depois, aplique essa fonte ao body (ou a qualquer outro elemento) como acima e remova o seletor de fonte padrão das opções.
Criando seu próprio seletor de fontes nas opções
Por enquanto, não é possível usar facilmente o seletor de fontes principal para adicionar sua própria fonte nas opções. Primeiro, precisamos dar ao usuário final a possibilidade de carregar pacotes personalizados (veja o próximo parágrafo: Uma olhada no seletor de fontes do Fruity)
Veja como proceder:
- Adicione duas fontes (my_custom_font e my_custom_other_font) ao seu tema, usando CDN ou servidor local
- Depois, no seu arquivo CSS, adicione duas novas classes:
.font-my_custom_font {
font-family: 'my_custom_font ';
}
.font-my_custom_other_font {
font-family: 'my_custom_other_font';
}
- No arquivo XML do seu tema, adicione uma opção de fonte (a padrão será my_custom_font) :
<options>
....
<font>my_custom_font</font>
</options>
- em option.twig, adicione seu seletor de fontes inserindo estas linhas (ainda não testado, então reclame no fórum se não funcionar):
<div class='row ls-space margin top-15 bottom-15 action_hide_on_inherit'>
<hr/>
</div>
<div class='row action_hide_on_inherit'>
<div class='col-sm-12'>
<div class='panel panel-default'>
<div class='panel-heading'>{{ "My custom fonts" | t }}</div>
<div class='panel-body'>
<div class='form-group row'>
<label for='simple_edit_font' class='control-label'>{{ "Select font:" | t }}</label>
<div class='col-sm-12'>
<select class='form-control selector_option_value_field' id='simple_edit_font' name='font'>
{% if templateConfiguration.sid is not empty or templateConfiguration.gsid is not empty %} //Shouldn't this be "theme" in stead of "template"?
{% set fontOptions = fontOptions ~ '<option value = "inherit" > Inherit</option>' %}
{% endif %}
<optgroup label="{{ "My Custom fonts" | t }}">
<option class="font-my_custom_font" value="custom_font" data-font-package="" >Custom</option>
<option class="font-my_custom_other_font" value="my_custom_other_font" data-font-package="" >Other</option>
</optgroup>
</select>
</div>
</div>
</div>
</div>
</div>
</div>
Agora seus usuários devem poder escolher entre essas duas fontes.
Uma olhada no seletor de fontes do Fruity
No futuro, daremos ao usuário final a possibilidade de carregar seus próprios pacotes de recursos, incluindo pacotes de fontes. Isso tornará muito fácil qualquer personalização de fontes.
Para entender os pacotes do Yii:
http://www.yiiframework.com/doc/api/1.1/CClientScript#packages-detail
Os pacotes do LimeSurvey são definidos em arquivos diferentes. Os pacotes de fontes são definidos aqui:
https://github.com/LimeSurvey/LimeSurvey/blob/4c40b61afb0dba8fd80154b50f5831045df8d814/application/config/fonts.php
Por exemplo, o pacote da fonte Noto é definido aqui:
https://github.com/LimeSurvey/LimeSurvey/blob/4c40b61afb0dba8fd80154b50f5831045df8d814/application/config/fonts.php#L47-L53
'font-noto' => array(
'devBaseUrl' => 'assets/fonts/',
'basePath' => 'fonts',
'css' => array(
'noto.css',
),
),
O arquivo noto.css que ele contém está aqui:
https://github.com/LimeSurvey/LimeSurvey/blob/4c40b61afb0dba8fd80154b50f5831045df8d814/assets/fonts/noto.css
Observe a definição da classe CSS ".font-noto" no final dele:
@font-face {
font-family: 'Noto Sans';
...
}
...
.font-noto{
font-family: 'Noto Sans';
}
Em seguida, no tema Vanilla, a fonte Noto é usada adicionando o pacote noto e definindo a opção de fonte como noto:
https://github.com/LimeSurvey/LimeSurvey/blob/70a1d99cd2ebe411597231a8bc746b4ca9e19584/themes/survey/vanilla/config.xml#L79
<packages>
....
<add>font-noto</add>
</packages>
<options>
....
<font>noto</font>
</options>
Em seguida, a classe de fonte do body é definida usando esse valor:
https://github.com/LimeSurvey/LimeSurvey/blob/70a1d99cd2ebe411597231a8bc746b4ca9e19584/themes/survey/vanilla/views/layout_global.twig#L76
<body class=" ... font-{{ aSurveyInfo.options.font }} ... " ... >
Naturalmente, o arquivo XML contém apenas os valores padrão da configuração do seu tema. Na verdade, esses valores são definidos e lidos no banco de dados (tabela "template_configuration" (Pergunta: "template_" ou "theme_"?) como strings JSON. O arquivo option.js apenas usa o valor do seletor de fontes das opções simples para alterar o valor dentro do formulário da aba avançada: https://github.com/LimeSurvey/LimeSurvey/blob/70a1d99cd2ebe411597231a8bc746b4ca9e19584/themes/survey/vanilla/options/options.js#L148-L174
Assim, quando a funcionalidade "carregar pacote de recursos" estiver disponível, será fácil adicionar um script que varra todos os pacotes de fontes existentes para adicioná-los ao seletor.
Adicionando opções de tema para controlar o posicionamento e a exibição de elementos do inquérito
Este tutorial mostrará como adicionar opções a um tema expandido para exibir elementos do inquérito em vários locais. Neste caso, criaremos opções de tema para mostrar o título do inquérito em dois locais diferentes.
Criar um tema personalizado
- Expanda o tema "bootswatch" conforme descrito acima.
- Copie custom.css para o tema local conforme descrito acima.
Criar novas opções de tema
- Copie o conteúdo de /themes/survey/bootswatch/options/ para /upload/themes/survey/yourThemeName/options/.
- Abra /upload/themes/survey/yourThemeName/options/options.twig em um editor e encontre "{# Bootstrap Bootswatch theme #}". Logo antes do elemento pai <div class='row'> dele, adicione isto:
{# Custom survey name in navbar #} <div class='row'> <div class='col-sm-12 col-md-6'> <div class='form-group row'> <label for='simple_edit_options_surveyname1' class='control-label'>Survey name in navbar</label> <div class='col-sm-12'> <div class="btn-group" data-toggle="buttons"> <label class="btn btn-default"> <input name='surveyname1' type='radio' value='on' class='selector_option_radio_field ' data-id='simple_edit_options_surveyname1'/> Yes </label> <label class="btn btn-default"> <input name='surveyname1' type='radio' value='off' class='selector_option_radio_field ' data-id='simple_edit_options_surveyname1'/> No </label> </div> </div> </div> </div> </div> <div class='row'> <hr/> </div> {# Custom survey name below progress bar #} <div class='row'> <div class='col-sm-12 col-md-6'> <div class='form-group row'> <label for='simple_edit_options_surveyname2' class='control-label'>Survey name below progress bar</label> <div class='col-sm-12'> <div class="btn-group" data-toggle="buttons"> <label class="btn btn-default"> <input name='surveyname2' type='radio' value='on' class='selector_option_radio_field ' data-id='simple_edit_options_surveyname2'/> Yes </label> <label class="btn btn-default"> <input name='surveyname2' type='radio' value='off' class='selector_option_radio_field ' data-id='simple_edit_options_surveyname2'/> No </label> </div> </div> </div> </div> </div> <div class='row'> <hr/> </div> - Abra /upload/themes/survey/yourThemeName/config.xml e adicione dois itens ao bloco "options" para que fique assim:
<options> <ajaxmode>on</ajaxmode> ... <surveyname1>on</surveyname1> <surveyname2>on</surveyname2> </options>
- Isso deve fornecer duas novas opções na tela Opções de tema, assim:

- Crie um novo diretório /upload/themes/survey/yourThemeName/views/subviews/header/.
- Copie /themes/survey/vanilla/views/subviews/header/nav_bar.twig para esse novo diretório.
- Abra /themes/survey/vanilla/views/subviews/header/nav_bar.twig e localize "{# Logo option #}". Abaixo dele, modifique a instrução IF para o logotipo/nome do questionário, de modo que fique assim:
{# Logo option #} {% if( aSurveyInfo.options.brandlogo == "on") %} <div class="{{ aSurveyInfo.class.navbarbrand }} logo-container" {{ aSurveyInfo.attr.navbarbrand }} > {{ image(aSurveyInfo.options.brandlogofile, aSurveyInfo.name, {"class": "logo img-responsive"}) }} </div> {% endif %} {% if( aSurveyInfo.options.surveyname1 == "on") %} <div class="{{ aSurveyInfo.class.navbarbrand }}" {{ aSurveyInfo.attr.navbarbrand }} > {{ aSurveyInfo.name }} </div> {% endif %} - Adicione algo como isto em /upload/themes/survey/yourThemeName/css/custom.css:
.navbar-brand { line-height: 60px; font-size: 32px; }
- Altere a opção de tema "Survey name in navbar" para "Sim"
- Você deverá ver isto:

Visualização modificada para o título do questionário abaixo da barra de progresso
- Crie um novo diretório /upload/themes/survey/yourThemeName/views/subviews/survey/group_subviews.
- Copie /themes/survey/vanilla/views/subviews/survey/group_subviews/group_container.twig para esse novo diretório.
- Abra /themes/survey/vanilla/views/subviews/survey/group_subviews/group_container.twig e adicione um elemento <h1> para o nome do questionário. Ele deve ficar assim:
<div class="{{ aSurveyInfo.class.groupcontainer }} space-col" {{ aSurveyInfo.attr.groupcontainer }}> {# Custom survey name #} {% if( aSurveyInfo.options.surveyname2 == "on") %} <h1 class="custom-survey-name">{{ aSurveyInfo.name }}</h1> {% endif %} {# Group Name #} {{ include('./subviews/survey/group_subviews/group_name.twig') }} {# Group Description #} {{ include('./subviews/survey/group_subviews/group_desc.twig') }} {# PRESENT THE QUESTIONS This is the main part. It will render each question for this group #} <!-- PRESENT THE QUESTIONS --> {% for aQuestion in aGroup.aQuestions %} {{ include('./subviews/survey/question_container.twig') }} {% endfor %} <!-- Hidden inputs --> {% if aGroup.show_last_group == true %} <input type='hidden' name='lastgroup' value='{{ aGroup.lastgroup }}' id='lastgroup' /> {% endif %} {% if aGroup.show_last_answer == true %} <input type='hidden' name='lastanswer' value='{{ aGroup.lastanswer }}' id='lastanswer' /> {% endif %} </div>
- Adicione algo como isto em /upload/themes/survey/yourThemeName/css/custom.css:
.navbar-brand { line-height: 60ph1.custom-survey-name { margin: 0; text-align: center; }
- Altere a opção de tema "Survey name below progress bar" para "Sim"
- Você deverá ver isto:

Downloads
- Exemplo de tema estendido: Test_survey_names.zip
Criando um tema do zero
Documentação em breve.
Por enquanto, apenas algumas dicas.
Estrutura do tema
Arquivos e diretórios
Ao criar um tema do zero, você não precisa respeitar a estrutura de arquivos/diretórios/CSS/JS do Vanilla. O CSS/JS obrigatório é adicionado pelo núcleo (você ainda pode removê-lo, se necessário).
Os únicos arquivos que o seu tema deve ter são os arquivos de layout:
- layout_global.twig : renderiza as páginas de resposta ao questionário
- layout_survey_list.twig : renderiza a lista de questionários (se este tema estiver definido como padrão)
- layout_errors.twig : usado para renderizar erros que impedem a exibição do questionário (ID de questionário incorreto, grupo vazio na pré-visualização do grupo etc.)
- layout_user_forms.twig: renderiza os formulários de usuário, como: código (participante do questionário) e registro.
- layout_print.twig : usado para imprimir o questionário em PDF
- layout_printanswers.twig: imprime as respostas
O conteúdo desses arquivos, e quais arquivos eles incluem ou não, fica inteiramente a seu critério. Todos os outros arquivos e diretórios que você encontra no Vanilla são totalmente opcionais; sinta-se à vontade para organizar seu código como preferir.
Conteúdo
No layout_global.twig do Vanilla, você verá que usamos uma variável chamada "include_content" para decidir o que exibir: https://github.com/LimeSurvey/LimeSurvey/blob/2398dda3b425da1a37d4611cd7963d39ac739987/themes/survey/vanilla/views/layout_global.twig#L114-L115
{% set sViewContent = './subviews/content/' ~ aSurveyInfo.include_content ~ '.twig' %}
{% include './subviews/content/outerframe.twig' with {'include_content': sViewContent } %}
aSurveyInfo.include_content informa qual ação está em andamento: exibindo perguntas? exibindo o resultado do envio? exibindo "Apagar tudo"? etc. Como você pode ver, no Vanilla criamos um arquivo a ser incluído por ação. Portanto, se quiser saber a lista de ações, basta consultar o diretório do Vanilla views/subviews/content e remover a extensão "twig": https://github.com/LimeSurvey/LimeSurvey/tree/2398dda3b425da1a37d4611cd7963d39ac739987/themes/survey/vanilla/views/subviews/content
- clearall.twig
- firstpage.twig
- load.twig
- mainrow.twig
- main.twig
- optin.twig
- optout.twig
- outerframe.twig
- printanswers.twig
- quotas.twig
- register.twig
- save.twig
- submit_preview.twig
- submit.twig
- userforms.twig
Se você já criou um tema para as versões 2.x do LimeSurvey, notará que a maioria deles corresponde aos antigos arquivos pstpl do LimeSurvey 2.x. Novamente, não há obrigação de criar esses arquivos, com esses nomes, nesse diretório em seu tema. Você poderia, por exemplo, simplesmente adicionar um grande switch no layout_global.twig com o HTML desejado para cada ação.
O manifesto config.xml
O manifesto do tema contém as principais informações sobre ele. Ao instalar um tema, o conteúdo do manifesto é carregado no banco de dados, em duas tabelas diferentes: template e template_configuration. Portanto, sempre que você modificar o manifesto de um tema, será necessário desinstalá-lo e reinstalá-lo (ou apenas reinicializá-lo). Como esse processo é incômodo durante o desenvolvimento de um tema, você pode forçar o uso direto do arquivo XML em vez das entradas do banco de dados. Para isso, em config.php ative o modo de depuração e defina 'force_xmlsettings_for_survey_rendering' como true.
A seção de metadados
Nada complexo: apenas as principais informações sobre o seu tema. Elas serão enviadas para a tabela templates_configuration.
<metadata>
<name>the_name_of_your_theme</name>
<title>The Title of your theme</title>
<creationDate>16/10/2017</creationDate>
<author>Your Name</author>
<authorEmail>your@email.org</authorEmail>
<authorUrl>http://www.yourwebsite.org</authorUrl>
<copyright>Your Copyright </copyright>
<license>Licence of your theme</license>
<version>version of your theme</version>
<apiVersion>3</apiVersion>
<description>Description of your theme</description>
<extends>parent_theme</extends>
</metadata>
Algumas observações:
- name: será usado como chave no banco de dados. Portanto, deve ser único e não deve ter caracteres especiais (nem espaços). Observe que maiúsculas e minúsculas não são consideradas.
- Title: será usado para exibir o nome do seu tema nas diferentes listas. Pode ter caracteres especiais.
- description: será usada na lista principal de temas do questionário. Pode conter caracteres especiais e até código HTML, usando
- extends: opcional, define os temas pai. Assim, se algum arquivo (twig/js/css/jpg etc.) não estiver presente neste tema, ele será procurado no tema pai.
A seção de arquivos
Esta é uma seção importante. Ela será enviada para a tabela template_configuration, nos campos files_css, files_js, files_print_css, como arrays JSON.
Ex.: a seção de arquivos do tema Material Premium:
<files>
<css>
<add>css/bootstrap-material-design.css</add>
<add>css/ripples.min.css</add>
<replace>css/ajaxify.css</replace>
<replace>css/theme.css</replace>
<replace>css/custom.css</replace>
<remove>awesome-bootstrap-checkbox/awesome-bootstrap-checkbox.css</remove>
</css>
<js>
<replace>scripts/theme.js</replace>
<replace>scripts/ajaxify.js</replace>
<add>scripts/material.js</add>
<add>scripts/ripples.min.js</add>
<replace>scripts/custom.js</replace>
</js>
<print_css>
<add>css/print_theme.css</add>
</print_css>
</files>
Todos os arquivos CSS/JS presentes nesta seção serão carregados no início do questionário (no modo Ajax. Se o modo Ajax estiver desativado, todos os arquivos serão recarregados a cada página, naturalmente).
Eles serão adicionados a um pacote de ativos (Asset Packet) do Yii, com base no nome do tema. Assim, quando o gerenciador de ativos estiver ligado (com o modo de depuração desativado), esses arquivos serão copiados para o diretório tmp junto com o restante do tema (para que você possa usar caminhos relativos no CSS e no JS para acessar os arquivos de imagem).
Sobre o gerenciador de ativos no Yii: https://www.yiiframework.com/wiki/148/understanding-assets
Sobre pacotes no Yii: http://www.yiiframework.com/doc/api/1.1/CClientScript#packages-detail
Eles usarão o sistema de herança. Isso significa que, se você adicionar um arquivo CSS/JS a um tema, mas ele não estiver presente nesse tema, o mecanismo procurará em todos os temas pai desse tema e usará o primeiro que encontrar. Assim, se um usuário estender o seu tema por meio do editor de temas, todos esses arquivos serão herdados no tema dele. As palavras-chave se referem a esse sistema de herança.
- add : adicionará o arquivo ao tema e a todos os temas que o herdam
- replace: substituirá o arquivo do seu tema pai
- remove: removerá o arquivo de qualquer pacote, inclusive do pacote principal (desde a versão 3.14)
Algumas observações sobre essas palavras-chave:
Dicas de herança
Como explicado anteriormente, a palavra-chave "add" pode se referir a um arquivo presente em um dos temas pai. Assim, você pode usar "add" para um arquivo nesta seção e, mesmo assim, não ter esse arquivo no seu tema, mas em um dos seus temas pai. O mecanismo procurará em todos os seus temas pai e usará o primeiro arquivo que encontrar. Se não encontrar o arquivo, e se o modo de depuração estiver ativado no config e o modo de depuração JS do frontend estiver ativado nas configurações globais, uma mensagem no console avisará você. Ex.: se adicionarmos em um my_theme: <add>css/unexisting.css</add>, veremos no console:
(¯`·._.·(¯`·._.· Theme Configuration Error ·._.·´¯)·._.·´¯)
Can't find file 'css/unexisting.css' defined in theme 'my_theme'Se o modo de depuração estiver desativado, nenhum erro será exibido. O mecanismo simplesmente ignorará as instruções add incorretas.
Quando usar add, quando usar replace e quando posso deixar para o tema pai?
Primeiro: add e replace são exatamente a mesma palavra-chave. Você pode usar uma ou outra, e o mecanismo fará o mesmo. Elas são distintas para os leitores humanos, para que entendam qual era a sua intenção.
Você não pode adicionar um arquivo com o mesmo nome do tema pai: ele sempre o substituirá. Ex.: se você tem um arquivo chamado "my_mother_theme/foo.css" e adiciona um arquivo chamado "foo.cs" no tema filho, apenas "daughter_theme/foo.css" será adicionado ao tema. Se você quiser manter "my_mother_theme/foo.css", basta escolher outro nome para "daughter_theme/foo.css", como "daughter_theme/bar.css". Portanto, a palavra-chave "add" pode ser usada como uma palavra-chave "replace".
Se você está se perguntando por quê: isso facilita muito a geração automática de temas herdados, pois copiar a seção de arquivos funciona de imediato (não é necessário renomear "add" para "replace" ao estender um dos arquivos).
Para deixar claro, vamos usar o exemplo do Fruity. Aqui está a sua seção de arquivos CSS:
<css>
<add>css/variations/sea_green.css</add>
<replace>css/animate.css</replace>
<replace>css/theme.css</replace>
<replace>css/custom.css</replace>
</css>
Se você olhar o arquivo custom.css no Fruity, ele é exatamente igual ao do Vanilla. Poderíamos excluir o arquivo custom.css dentro do Fruity e o do Vanilla seria carregado. Também poderíamos remover a instrução <replace>custom.css</replace> do manifesto do Fruity; a instrução do Vanilla seria usada e o custom.css do Vanilla seria carregado.
Então por que usamos a instrução <replace>custom.css</replace> no manifesto do Fruity? A resposta é simples: porque queremos que o usuário final possa estender o tema Fruity, modificar o arquivo no seu tema local e carregar esse arquivo modificado a partir do seu tema herdado. Para entender, basta estender o Fruity e dar uma olhada no tema estendido. O tema estendido nem sequer possui o arquivo custom.css. Portanto, o do Fruity será usado. Mas, se o usuário criar esse arquivo no tema estendido (clicando em "Estender" no Editor de temas), esse arquivo será carregado a partir do tema dele.
Então, em geral:
se você criar um tema do zero, sem estender nenhum tema, basta usar a instrução add para adicionar seus arquivos css/js. Simples assim.
se você criar um tema estendendo outro tema e não quiser que os usuários possam estender o arquivo css/js do tema pai: não use a instrução add no seu manifesto. Os arquivos ainda serão carregados a partir da configuração do tema pai.
se você criar um tema estendendo outro tema e quiser substituir um arquivo do tema pai: use a palavra-chave replace (a palavra-chave add terá o mesmo resultado).
se você criar um tema estendendo outro tema, não substituir um determinado arquivo css/js, mas quiser que os usuários possam estender esse arquivo: use a instrução "replace" no seu manifesto para esse arquivo. Mesmo que você não substitua o arquivo, ao usar a palavra-chave replace no manifesto você permite que o usuário o faça, se quiser.
Apenas este último caso exige um pouco de ginástica mental para ser compreendido; todos os outros casos são triviais.
Você também pode registrar arquivos CSS e JS diretamente a partir do código twig. Esses arquivos serão carregados somente quando o arquivo twig for solicitado. Se você quiser que os usuários possam herdar esses arquivos JS/CSS a partir do Editor de temas, lembre-se de usar as funções Template:RegisterTemplateCssFile('my style.css') e Template:RegisterTemplateScript('my script.js'). Se você não usar essas funções, seu tema poderá funcionar, mas a herança nele ficará comprometida. É a mesma lógica da função Template:Image('my picture.jpg')
A palavra-chave remove
A palavra-chave remove está disponível somente a partir da versão 3.14. Com ela, você pode remover qualquer arquivo css/js de qualquer pacote, mesmo os principais. Ela é usada no Material Premium Theme para remover os arquivos do Awesome Bootstrap Checkbox:
<remove>awesome-bootstrap-checkbox/awesome-bootstrap-checkbox.css</remove>
Portanto, você deve usar exatamente a mesma sintaxe do arquivo do pacote (ex.: "awesome-bootstrap-checkbox.css" sozinho, sem o caminho da pasta, não funcionaria). Você encontrará a lista completa dos pacotes principais e seus arquivos em /application/config/packages.php e config/third_party.php. Por exemplo, para awesome-bootstrap-checkbox.css: https://github.com/LimeSurvey/LimeSurvey/blob/2398dda3b425da1a37d4611cd7963d39ac739987/application/config/packages.php#L54-L56
'css'=> array(
'awesome-bootstrap-checkbox/awesome-bootstrap-checkbox.css',
),
Outra maneira de encontrar o nome exato a ser usado na tag remove é ativar o gerenciador de assets (desativando o modo de depuração ou definindo 'use_asset_manager'=>true no config). Assim, o caminho a ser usado será o que vem logo após o diretório aleatório no diretório tmp. Por exemplo, para awesome-bootstrap-checkbox.css:
<link rel="stylesheet" type="text/css" href="/tmp/assets/cbc4e3cb/awesome-bootstrap-checkbox/awesome-bootstrap-checkbox.css" />
Arquivos que você não deve remover:
jquery-3.1.1.min.js : necessário
jquery-migrate-3.0.0.min.js : necessário
survey.js : necessário
moment-with-locales.min.js : necessário para o tipo de pergunta de data (e para alguns outros, acho)
em_javascript.js : necessário para todo o JavaScript do ExpressionScript
A seção de opções
Esta seção refere-se às opções do seu tema. Ela será usada para preencher o campo "options" da tabela template_configuration como um array JSON.
Informações adicionais
Algumas observações
NOTA: se você editar o arquivo XML de um tema, deverá desinstalar e reinstalar o tema para que a alteração seja considerada.
NOTA: para evitar isso, você pode forçar o uso do XML em vez do banco de dados. No config.php, ative o modo de depuração e remova o comentário de:
'force_xmlsettings_for_survey_rendering' => true, // Uncomment if you want to force the use of the XML file rather than DB (for easy theme development)
Cuidado: tudo será carregado a partir do XML (inclusive as opções, etc.)
NOTA: se você editar manualmente os arquivos CSS/JS (sem usar o Editor de temas) e o modo de depuração estiver desativado, agora é possível forçar a limpeza dos assets. Em "Definições globais", na aba "Geral", clique no botão "Limpar cache de assets".
NOTA: se você remover a seção
