Novo sistema de temas no LS3.x
From LimeSurvey Manual
Introdução
Atenção: nas versões anteriores do LimeSurvey, os ficheiros que definem o aspeto do inquérito, a forma como este é apresentado em termos de cores, tipos de letra, esquema e (algum) comportamento eram designados por "modelo" (template). Devido a novas perspetivas, passam agora a chamar-se "tema", ficando a designação "modelo" reservada para inquéritos de exemplo.
Nesta página, vai aprender a:
- Usar o novo sistema de temas do LimeSurvey 3.0.
- Usar a herança para gerir os seus próprios temas.
- Adicionar uma imagem ao seu tema
- Gerir as opções de tema dos seus inquéritos e grupos de inquéritos
O LimeSurvey 3 introduz um novo sistema completo de motor de temas, baseado em Twig 1.29 e Bootstrap, que permite a herança de temas e as opções de tema. Remove por completo o antigo sistema de palavras-chave de substituição. Assim, 100% do HTML do frontend pode agora ser personalizado. Por exemplo, no antigo sistema de temas existia uma palavra-chave {ASSESSMENTS} que era substituída pelo HTML da avaliação no momento da execução. Quem criava o tema não tinha forma de personalizar este HTML (a não ser com JavaScript). Agora, existe um ficheiro chamado assessments.twig que contém a lógica (escrita em Twig) para gerar esse HTML. Nestas páginas, damos-lhe algumas explicações sobre como usar este novo motor de temas.
Edição através da interface de administração
Lista de temas
No painel de controlo de administração existe agora uma caixa para aceder à lista de temas:

A lista está dividida em 5 colunas:
- uma pré-visualização do tema: é apenas um ficheiro 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: uma cadeia de caracteres definida no seu manifesto
- o tipo de tema: Tema principal (fornecido com o LimeSurvey), Tema do utilizador (adicionado na pasta de carregamento), Tema XML (não carregado na base de dados)
- Expandir: se o tema expande outro tema, o nome deste será indicado aqui
- Alguns botões de ação:
- Instalar: carrega o manifesto de um tema para o adicionar à base de dados e torná-lo disponível para seleção ao nível do inquérito
- Desinstalar: elimina as entradas de configuração de um tema na base de dados
- Editor de temas: reencaminha-o para o editor de temas
- Opções de tema: leva-o à 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, quando abre um tema principal, não o pode editar. Mas agora, em vez de um botão “copiar”, tem um botão “expandir”.

Uma breve visão geral do conceito de herança de temas
No LS3, um tema pode agora herdar de outro tema, ou seja, pode “expandir” outro tema. Isto significa que a pasta do tema ficará praticamente vazia, contendo apenas os ficheiros (vistas, folhas de estilo, scripts, recursos, etc.) que diferem dos originais. Desta forma, será fácil criar uma frota de temas para os seus diferentes utilizadores sem ter de manter muitos temas diferentes. Por exemplo: pode ter o seu próprio tema caseiro e depois uma versão para uma empresa (com o seu logótipo, o seu estilo, talvez uma hiperligação para o seu sítio Web no rodapé, etc.), outra versão para outra empresa, etc. Se depois atualizar o CSS ou o esquema global do seu tema personalizado, todos os temas que herdam dele serão atualizados automaticamente. Note que a herança é recursiva: um tema pode expandir um tema que expande outro, e assim sucessivamente.
Novidades na interface de utilizador
Para expandir o tema Monochrome do LimeSurvey, aceda à lista de temas e clique no botão “Editor de temas” do tema Monochrome. Depois, clique em “Expandir” e valide o novo nome “extends_monochrome”.
Se agora for à pasta de carregamento (com o seu cliente de ficheiros/FTP), verá que foi criada uma nova pasta: upload/themes/extends_monochrome Contém um ficheiro XML e pastas, mas a maioria das pastas está vazia. Não tem vistas, nem CSS, nem JS. Contudo, pode selecionar este tema num inquérito como qualquer outro e ele terá exatamente o mesmo aspeto que o tema Monochrome.

O editor de temas para o tema extends_monochrome tem este aspeto:

Não há grandes diferenças em relação ao antigo editor de temas. Vejamos as principais:
- A palavra-chave herdado na lista de ficheiros. Significa que o ficheiro não está presente na pasta do tema e que será usado o ficheiro do tema original.

- O editor principal ( editor ACE ) mostra o conteúdo do ficheiro selecionado. Os ficheiros contêm não só HTML, CSS ou JS, mas também instruções Twig. Essas instruções Twig dão-nos a possibilidade de levar alguma lógica para as vistas do tema que antes estavam escondidas no núcleo e que agora podem ser personalizadas.

- É por isso que agora tem mais tipos de ecrã disponíveis no seletor do menu superior. Notará páginas como ‘Lista de inquéritos’, ‘Carregar’, ‘Gravar’, ‘Erro’, ‘Registo’, ‘Avaliações’, ‘Imprimir/Gravar as suas respostas’ que antes não estavam disponíveis ou que não podiam realmente ser personalizadas.

- A hiperligação ‘Dica’ no fundo da lista de ficheiros mostra-lhe a forma Twig de adicionar uma imagem ao seu HTML

- O botão ‘Gravar alterações’ passa a ser um botão Copiar para um tema local e guardar alterações

Exemplo rápido: adicionar uma imagem
O botão Copiar para um tema local e guardar alterações faz exatamente o que diz: se editar algo dentro do ficheiro e depois clicar nesse botão, o ficheiro será copiado para o tema que está a editar e as suas alterações serão gravadas.
Por exemplo: clique no ficheiro layout_global.twig e, imediatamente antes do bloco content ( {% block content %}), adicione o texto “TEST” e clique no botão. Verá que a etiqueta do ficheiro mudou de “herdado” para “local” e que o botão é agora um simples botão Gravar alterações.

Se abrir um explorador de ficheiros e for à pasta upload/themes/extends_monochrome/views/, verá que contém apenas um ficheiro, o layout_global.twig, e que a cadeia de caracteres “TEST” está lá.

Agora, em vez de adicionar um texto qualquer, vamos adicionar uma imagem. Se clicar na hiperligação Dica, ela diz-lhe:
Para usar uma imagem num ficheiro .twig:
{{ image('./files/myfile.png', 'alt-text for my file', {"class": "myclass"}) }}
Se leu a documentação do Twig (e deveria tê-lo feito neste ponto), sabe que {{ function( ) }} escreve no ecrã o resultado de uma função. Aqui, a função é image( ).
Se não compreender o código, não se preocupe: não precisa de saber como funciona, mas sim porquê e como a usar.
Deve usar a função image() por duas razões:
- A função image percorre o tema para encontrar a imagem. Se o tema em que está a trabalhar expande outro tema e se copiar o ficheiro onde inseriu a imagem para o tema local, mas essa imagem não for copiada para o tema local, a função percorrerá a árvore de herança do tema para encontrar onde essa imagem está.
- Usa o gestor de recursos (asset manager), pelo que melhora o desempenho do seu tema. Consulte a documentação do gestor de recursos do Yii para obter mais informações: http://www.yiiframework.com/wiki/148/understanding-assets/
Assim, para adicionar uma imagem ao seu tema:
- basta carregá-la como habitualmente com o carregador de ficheiros à direita e depois adicioná-la onde quiser em qualquer ficheiro twig:
{{ image('./files/myfile.png') }}
- Se quiser adicionar um texto alternativo para a sua imagem (para leitores de ecrã e validação de HTML), adicione:
{{ image('./files/myfile.png'), ‘o meu texto alternativo’ }}
- Se quiser adicionar um atributo class e um id:
{{ image('./files/myfile.png'), ‘o meu texto alternativo’, {“class”: “a_nice_css_class”, “id”: “any_id”} }}
Algumas coisas na nossa lista de tarefas
- Dar aos utilizadores a possibilidade de carregar um ficheiro de pré-visualização personalizado a partir do próprio editor
- Adicionar um botão para eliminar o ficheiro local e voltar ao estado herdado
- Copiar apenas a imagem usada nos ficheiros CSS (listando-as no manifesto como ficheiros a copiar)
- Indicar qual o tema que o tema atual expande (se existir)
Opções de tema
Outra novidade do LS3 é a página de opções de tema. Como veremos mais adiante, quem cria temas pode criar as suas próprias opções e até a sua própria página de opções de administração. Aqui, veremos rapidamente como funciona a página de opções dos temas principais. Para aceder às opções de tema ao nível global: clique em “Opções de tema” na lista de temas
Opções avançadas
Ao abrir o separador Opções de tema, pode optar por editar as Opções simples ou as Opções avançadas. As “Opções avançadas” são apenas um formulário simples que lhe dá acesso aos principais campos de configuração do tema na base de dados. Para compreender como funciona, deve ler também sobre o ficheiro XML e a criação de um tema de raiz. Por isso, é bastante complexo e destinado a utilizadores avançados.
No entanto, se pretender efetuar a edição das configurações avançadas, clique no separador Opções avançadas

- Ficheiros CSS: Os ficheiros CSS que devem ser adicionados ao tema;
- Ficheiros JS: Os ficheiros JS que devem ser adicionados ao tema;
- Ficheiros CSS para impressão: Os ficheiros CSS a carregar ao imprimir um tema;
- Opções: Este campo inclui as opções (e o respetivo valor) que devem ser processadas na vista do tema;
- Nome do framework CSS: O nome do framework CSS a carregar. Por agora, apenas Bootstrap ou nenhum;
- CSS do framework CSS: Neste campo, pode substituir o bootstrap.css principal por uma versão personalizada diferente;
- JS do framework CSS: Neste campo, o ficheiro boostrap.js principal pode ser substituído por uma versão personalizada diferente;
- Pacotes a carregar: Nesta configuração pode carregar alguns pacotes de recursos principais do LimeSurvey.
Verá um campo de carregamento no topo, que lhe permite carregar um ficheiro para a pasta de ficheiros do tema. Estes parâmetros podem ser utilizados para alterar por completo o aspeto do tema.
Opções simples
A página de opções simples vem do próprio modelo. É feita através de um ficheiro twig e de algum JavaScript dentro da pasta /options do tema: https://github.com/LimeSurvey/LimeSurvey/tree/develop/templates/default/options (hiperligação quebrada)

A página de opções simples limita-se a preencher os campos do formulário avançado. Pode verificá-lo ativando ou desativando uma definição na página simples e vendo como o campo correspondente no formulário avançado é modificado em conformidade. Por exemplo, nas opções simples do tema predefinido, se alterar o tema Bootswatch para “Darkly” e, em seguida, clicar no separador das opções avançadas (mesmo sem guardar), verá que o campo “Cssframework Css” mudou de
{"replace": [["css/bootstrap.css","css/flatly.css"]]}
para
{"replace": [["css/bootstrap.css","css/darkly.css"]]}
Estas são as diferentes opções simples dos temas principais:
- Ajax mode: define se a Página seguinte deve ser carregada através de ajax (mais rápido) ou através de recarregamento da página (melhor para efeitos de debug)
- Imagem de fundo: se estiver definido como Sim, a imagem chamada pattern.png será carregada (será substituída por um seletor de ficheiros na versão Master)
- Box container: se estiver definido como Não, as perguntas não ficarão contidas numa caixa (para poder utilizar matrizes grandes, maiores do que a largura do ecrã)
- Brandlogo: se estiver definido como não, o nome do inquérito será apresentado na Barra superior; caso contrário, pode selecionar uma das imagens existentes na pasta de ficheiros para ser utilizada como logótipo.
- Animar corpo: se estiver definido como sim, pode escolher uma das animações a aplicar quando o corpo do inquérito é carregado
- Animar pergunta: o mesmo para as perguntas
- Animate alerts: o mesmo para os alertas
- Tema Bootstrap: aqui pode escolher um tema Bootstrap a carregar. Provêm do Bootswatch https://bootswatch.com/3/
A biblioteca utilizada para as animações é a animate.css: https://daneden.github.io/animate.css/
Naturalmente, um fornecedor de temas pode adicionar a sua própria biblioteca de animações ou não utilizar qualquer biblioteca de animações.
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. Isto significa que, para um determinado tema, pode ter uma configuração ao nível
- global (a que acabámos de ver, acessível a partir da lista de temas)
- do grupo de inquéritos
- e uma última ao nível do inquérito.
Cada parâmetro de um determinado nível pode herdar do nível superior: herança do grupo de inquéritos. Vejamos primeiro o nível do grupo de inquéritos.
Ao nível do grupo de inquéritos
De facto, uma das outras grandes novidades do LS3 é o sistema de grupos de inquéritos. Agora pode criar diferentes grupos para organizar os seus inquéritos. Para aceder, vá à Lista de inquéritos e clique no separador Grupos de inquéritos:

Nesta lista existem dois botões de ação. Se o grupo estiver vazio, pode eliminá-lo. Caso contrário, pode sempre editá-lo. Ao clicar no botão de edição, acede à página de configuração do Grupo de inquérito:

O terceiro separador desta página chama-se “Opções de tema para este grupo de inquéritos”. Se clicar nele, verá a mesma lista de temas que na lista de temas, exceto que aqui só o botão de opções está visível (o Editor de temas só pode ser acedido a partir da lista principal).
Agora, se clicar na opção do tema predefinido, verá o seguinte:

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

Ao nível do inquérito
Ao editar um inquérito, no menu da barra esquerda, verá uma nova entrada “Opções de tema”. Esta leva-o à página de opções do tema selecionado para o inquérito atual. Encontrará o mesmo sistema de herança que no grupo de inquéritos, mas desta vez, herdar significa que a definição será herdada do Grupo de inquérito do inquérito.

Exemplo de caso de utilização
Imagine que utiliza um único tema para diferentes empresas (A e B). Define as suas opções favoritas ao nível global (por exemplo: ajax ativo, animar corpo com deslize, alertas com pulsação). Depois cria um grupo de inquéritos para cada empresa: um grupo para a empresa A, que alojará todos os inquéritos desta empresa, e outro para a empresa B, que alojará todos os inquéritos da empresa B. A este nível, definirá apenas o logótipo e o fundo, e deixará as restantes opções herdar. Assim, todos os inquéritos do grupo A utilizarão o logótipo da empresa A, e todos os inquéritos do grupo B o logótipo da empresa B. Para um dos inquéritos da empresa A, pode utilizar um fundo diferente, relacionado com o tema do inquérito: basta alterar o fundo nas opções ao nível do inquérito. Se alguém da empresa B lhe disser que o alerta com pulsação é demasiado agressivo e que preferiria algo mais suave, como um desvanecimento, basta alterar a Animação de alerta ao nível do Grupo de inquérito B e todos os inquéritos deste grupo passarão a utilizar essa animação. Se a empresa A alterar o seu logótipo, pode alterá-lo ao nível do Grupo de inquérito A, e todos os inquéritos deste grupo utilizarão o novo logótipo.
FAQ sobre a personalização de temas
Encontrará aqui algumas respostas a perguntas feitas no fórum que poderão ajudá-lo a personalizar o seu tema.
Personalizar CSS/JS: lidar com o gestor de assets ("porque é que as minhas alterações não são aplicadas?")
Se estiver a tentar atualizar o CSS/JS de um tema editando diretamente o código com o seu editor favorito, pode surpreender-se por as suas alterações não serem aplicadas.
Desde a versão 2.50, o LS utiliza o gestor de assets do Yii:
Documentação do Yii sobre Assets
Move os ficheiros CSS/JS de um tema para uma subpasta de tmp/ com uma cadeia de caracteres aleatória (por exemplo: "tmp/1ef64ml/"). Assim, se fizer qualquer alteração a um ficheiro css/js e o comunicar ao gestor de assets, os ficheiros são copiados para uma nova subpasta com um novo nome, de modo que a cache do navegador do utilizador é atualizada e este vê o novo css/js. Caso contrário, teria de limpar a cache do navegador.
Aqui estão as ligações CSS no cabeçalho quando o gestor de assets está ativo:
Como pode ver, todas se referem às subpastas de tmp/.
Aqui estão as ligações CSS no cabeçalho quando o gestor de assets está desativado:
Como pode ver, apontam para os ficheiros reais do tema.
Assim, quando está a editar o CSS/JS de um tema, tem várias possibilidades:
- Pode utilizar o Editor de temas do LS: ele trata do gestor de assets e não tem de se preocupar com nada
- Pode ativar o modo debug: desativará o gestor de assets, pelo que os ficheiros css/js reais dos seus temas são chamados (mas, nesse caso, tem de atualizar a cache do navegador em cada carregamento)
- Pode atualizar a cache de assets: em Configurações globais -> Geral -> Limpar cache de assets
Utilizar o Editor de temas ajudá-lo-á a compreender a arquitetura do novo motor de temas.
Além disso, se estiver a personalizar o fruity, tenha cuidado com a especificidade do CSS: a maioria das definições utiliza o seletor ".fruity" (uma das classes do elemento body).
Adicionar tipos de letra personalizados ao meu tema
A forma fácil: utilizar a CDN de tipos de letra do Google
O tema de inquérito Bootswatch utiliza a CDN de tipos de letra do Google. Vejamos como 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, o tipo de letra Lato é utilizado através de regras CSS: https://github.com/thomaspark/bootswatch/blob/master/dist/flatly/bootstrap.css#L72
body {
...
font-family: "Lato";
...
}
Pode utilizar qualquer tipo de letra do Google desta forma no seu tema personalizado. Claro que deve eliminar o seletor de tipo de letra das opções do seu tema. Elimine estas linhas em options.twig: https://github.com/LimeSurvey/LimeSurvey/blob/70a1d99cd2ebe411597231a8bc746b4ca9e19584/themes/survey/vanilla/options/options.twig#L209-L230
Utilizar um tipo de letra local
Claro que também pode descarregar os ficheiros do tipo de letra e utilizá-los a partir do servidor local, em vez do CDN do Google (melhor para a privacidade). Para ter um exemplo de como fazer, eis a nossa versão local do tipo de letra 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');
}
...
Pode utilizar uma definição muito semelhante no ficheiro CSS do seu tema e, depois, copiar o ficheiro NotoSans-Regular.ttf para a pasta css/font-src/ do seu tema.
Depois, aplique esse tipo de letra ao seu body (ou a qualquer outro elemento) como acima e elimine o seletor de tipo de letra predefinido das opções.
Criar o seu próprio seletor de tipo de letra nas opções
Por agora, não é possível utilizar facilmente o seletor de tipo de letra principal para adicionar o seu próprio tipo de letra às opções. Primeiro, é necessário dar ao utilizador final a possibilidade de carregar pacotes personalizados (veja o parágrafo seguinte: Uma vista sobre o seletor de tipo de letra do Fruity)
Eis como proceder:
- Adicione dois tipos de letra (my_custom_font e my_custom_other_font) ao seu tema, utilizando CDN ou servidor local
- Depois, no seu ficheiro 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 ficheiro XML do seu tema, adicione uma opção de tipo de letra (a predefinida será my_custom_font) :
<options>
....
<font>my_custom_font</font>
</options>
- em option.twig, adicione o seu seletor de tipo de letra acrescentando estas linhas (ainda não testado, por isso queixe-se 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, os seus utilizadores devem poder escolher entre esses dois tipos de letra.
Uma vista sobre o seletor de tipo de letra do Fruity
No futuro, daremos ao utilizador final a possibilidade de carregar os seus próprios pacotes de recursos, incluindo pacotes de tipos de letra. Isto tornará muito fácil qualquer personalização de tipos de letra.
Para compreender os pacotes do Yii:
http://www.yiiframework.com/doc/api/1.1/CClientScript#packages-detail
Os pacotes do LimeSurvey estão definidos em diferentes ficheiros. Os pacotes de tipos de letra estão definidos aqui:
https://github.com/LimeSurvey/LimeSurvey/blob/4c40b61afb0dba8fd80154b50f5831045df8d814/application/config/fonts.php
Por exemplo, o pacote do tipo de letra Noto está 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 ficheiro noto.css que contém está aqui:
https://github.com/LimeSurvey/LimeSurvey/blob/4c40b61afb0dba8fd80154b50f5831045df8d814/assets/fonts/noto.css
Repare na definição da classe CSS ".font-noto" no final do mesmo:
@font-face {
font-family: 'Noto Sans';
...
}
...
.font-noto{
font-family: 'Noto Sans';
}
Depois, no tema Vanilla, o tipo de letra Noto é utilizado adicionando o pacote noto e definindo a opção de tipo de letra 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>
Depois, a classe de tipo de letra do body é definida utilizando este valor:
https://github.com/LimeSurvey/LimeSurvey/blob/70a1d99cd2ebe411597231a8bc746b4ca9e19584/themes/survey/vanilla/views/layout_global.twig#L76
<body class=" ... font-{{ aSurveyInfo.options.font }} ... " ... >
Claro que o ficheiro XML contém apenas os valores predefinidos da configuração do seu tema. Na realidade, esses valores são definidos e lidos na base de dados (tabela "template_configuration" (Pergunta: "template_" ou "theme_"?) como cadeias json. O ficheiro option.js limita-se a utilizar o valor do seletor de tipo de letra das opções simples para alterar o valor no formulário do separador avançado: 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 analise todos os pacotes de tipos de letra existentes para os adicionar ao seletor.
Adicionar opções de tema para controlar o posicionamento e a apresentação de elementos do inquérito
Este tutorial mostra como adicionar opções a um tema expandido para apresentar elementos do inquérito em várias localizações. Neste caso, vamos criar opções de tema para mostrar o título do inquérito em duas localizações diferentes.
Criar um tema personalizado
- Expanda o tema "bootswatch" como descrito acima.
- Copie custom.css para o tema local como 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 num editor e pesquise "{# Bootstrap Bootswatch theme #}". Imediatamente antes do respetivo elemento pai <div class='row'>, 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>
- Isto deverá dar-lhe duas novas opções no ecrã Opções de tema, como se vê a seguir:

- Crie uma nova pasta /upload/themes/survey/yourThemeName/views/subviews/header/.
- Copie /themes/survey/vanilla/views/subviews/header/nav_bar.twig para essa nova pasta.
- Abra /themes/survey/vanilla/views/subviews/header/nav_bar.twig e pesquise "{# Logo option #}". Por baixo, modifique a instrução IF do logótipo/nome do inquérito, para 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 a /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"
- Deverá ver isto:

Vista modificada para o título do inquérito por baixo da barra de progresso
- Crie uma nova pasta /upload/themes/survey/yourThemeName/views/subviews/survey/group_subviews.
- Copie /themes/survey/vanilla/views/subviews/survey/group_subviews/group_container.twig para essa nova pasta.
- Abra /themes/survey/vanilla/views/subviews/survey/group_subviews/group_container.twig e adicione um elemento <h1> para o nome do inquérito, para que fique 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 a /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"
- Deverá ver isto:

Transferências
- Exemplo de tema expandido: Test_survey_names.zip
Criar um tema de raiz
Documentação em breve.
Por agora, apenas algumas sugestões.
Estrutura do tema
Ficheiros e pastas
Quando cria um tema de raiz, não precisa de respeitar a estrutura de ficheiros/pastas/css/js do Vanilla. O css/js obrigatório é adicionado pelo núcleo (pode, mesmo assim, eliminá-lo se necessário)
Os únicos ficheiros que o seu tema tem de ter são os ficheiros de layout:
- layout_global.twig : apresenta as páginas para responder ao inquérito
- layout_survey_list.twig : apresenta a lista de inquéritos (se este tema estiver definido como predefinido)
- layout_errors.twig : utilizado para apresentar erros que impedem a apresentação do inquérito (ID do inquérito errado, grupo vazio na pré-visualização do grupo, etc.)
- layout_user_forms.twig: apresenta os formulários de utilizador, como: código (participante do inquérito) e registo.
- layout_print.twig : utilizado para imprimir o inquérito em PDF
- layout_printanswers.twig: imprime as respostas
O conteúdo desses ficheiros, e os ficheiros que incluem ou não, fica inteiramente ao seu critério. Todos os outros ficheiros e pastas que encontra no Vanilla são puramente opcionais; organize o seu código da forma que preferir.
Conteúdo
No layout_global.twig do Vanilla, verá que utilizamos uma variável chamada "include_content" para decidir o que mostrar 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 indica-lhe qual a ação em curso: mostrar perguntas? mostrar o resultado do envio? mostrar apagar tudo? etc. Como pode ver, no vanilla criamos um ficheiro a incluir por ação. Assim, se quiser saber a lista de ações, basta consultar a pasta 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 já criou um tema para as versões 2.x do LimeSurvey, notará que a maioria deles corresponde aos antigos ficheiros pstpl do LimeSurvey 2.x. Mais uma vez, não é obrigatório criar esses ficheiros, com esses nomes, nesta pasta. Poderia, por exemplo, adicionar apenas um grande switch no layout_global.twig com o HTML pretendido para cada ação.
O manifesto config.xml
O manifesto do tema contém as principais informações sobre o seu tema. Quando instala um tema, o conteúdo do manifesto é carregado na base de dados, em duas tabelas diferentes: template e template_configuration. Assim, sempre que modificar o manifesto de um tema, tem de o desinstalar e reinstalar (ou simplesmente reinicializá-lo). Como este processo é incómodo durante o desenvolvimento de um tema, pode forçar a utilização direta do ficheiro XML em vez das entradas da base de dados. Para tal, em config.php ligue o modo debug e defina 'force_xmlsettings_for_survey_rendering' como true.
A secção de metadados
Nada complexo: apenas as informações principais sobre o seu tema. 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á utilizado como chave na base de dados. Por isso tem de ser único e não deve ter carateres especiais (nem espaços). Note que não se distingue maiúsculas de minúsculas
- Title: será utilizado para mostrar o nome do seu tema nas diferentes listas. Pode ter carateres especiais
- description: será utilizada na lista principal de temas de inquérito. Pode conter carateres especiais e até código HTML, utilizando
- extends: opcional, define os temas pai. Assim, se algum ficheiro não estiver presente neste tema (twig/js/css/jpg, etc.), será procurado no tema pai
A secção de ficheiros
Esta é importante. Será enviada para a tabela template_configuration, nos campos files_css, files_js, files_print_css, como matrizes JSON.
Ex.: a secção de ficheiros do Material Premium Theme:
<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 ficheiros CSS/JS presentes nesta secção serão carregados no início do inquérito (em modo ajax. Se o modo ajax estiver desligado, então, claro, todos os ficheiros são recarregados em cada página).
Serão adicionados a um pacote de recursos (Asset Packet) do Yii com base no nome do tema. Assim, quando o Asset Manager está ligado (com o modo debug desligado), esses ficheiros serão copiados para a pasta tmp com o resto do tema (para que possa utilizar caminhos relativos no CSS e no JS para chegar aos ficheiros de imagem).
Sobre o Asset Manager 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
Utilizarão o sistema de herança. Isto significa que, se adicionar um ficheiro CSS/JS a um tema, mas este não estiver presente no tema, o motor procurará em todos os temas pai desse tema e utilizará o primeiro que encontrar. Assim, se um utilizador expandir o seu tema através do editor de temas, todos esses ficheiros serão herdados no tema dele. As palavras-chave referem-se a este sistema de herança.
- add : adiciona o ficheiro ao tema e a todos os temas que o herdam
- replace: substitui o ficheiro do seu tema pai
- remove: elimina o ficheiro de qualquer pacote, mesmo do pacote principal (desde a versão 3.14)
Algumas observações sobre estas palavras-chave:
Dicas sobre herança
Como explicado anteriormente, a palavra-chave "add" pode referir-se a um ficheiro existente num dos temas pai. Assim, pode "adicionar" um ficheiro nesta secção sem que esse ficheiro exista no seu tema, mas sim num dos seus temas pai. O motor pesquisa em todos os temas pai e utiliza o primeiro que encontrar. Se não encontrar o ficheiro, e o modo debug estiver ativo no config e o modo debug de JavaScript do frontend estiver ativo nas definições globais, será apresentada uma mensagem de aviso na consola. Ex.: se adicionarmos em my_theme: <add>css/unexisting.css</add>, na consola veremos:
(¯`·._.·(¯`·._.· Theme Configuration Error ·._.·´¯)·._.·´¯)
Can't find file 'css/unexisting.css' defined in theme 'my_theme'Se o modo debug estiver desativado, não será apresentado qualquer erro. O motor limitar-se-á a ignorar as instruções add incorretas.
Quando usar add, quando usar replace e quando posso deixar isso ao tema pai?
Primeiro: add e replace são exatamente a mesma palavra-chave. Pode utilizar uma ou outra, pois o motor fará o mesmo. Distinguem-se para os leitores humanos, para que percebam qual era a sua intenção.
Não é possível adicionar um ficheiro com o mesmo nome do tema pai: este substituirá sempre o outro. Ex.: se tiver um ficheiro chamado "my_mother_theme/foo.css" e adicionar um ficheiro chamado "foo.cs" no tema filho, apenas "daughter_theme/foo.css" será adicionado ao tema. Se quiser manter "my_mother_theme/foo.css", escolha simplesmente outro nome para "daughter_theme/foo.css", como "daughter_theme/bar.css". Assim, a palavra-chave "add" pode ser utilizada como palavra-chave "replace".
Se se pergunta porquê: isto facilita muito a geração automática de temas herdados, pois copiar a secção de ficheiros funciona logo de origem (não é necessário mudar "add" para "replace" ao expandir um ficheiro).
Para tornar isto claro, vejamos o exemplo do Fruity. Eis a sua secção de ficheiros 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 observar o ficheiro custom.css no fruity, verá que é exatamente igual ao do vanilla. Poderíamos eliminar o ficheiro custom.css dentro do fruity e seria carregado o do vanilla. Também poderíamos eliminar a instrução <replace>custom.css</replace> do manifesto do Fruity, e seria utilizada a instrução do vanilla, sendo carregado o custom.css do vanilla.
Então porque utilizamos a instrução <replace>custom.css</replace> no manifesto do fruity? A resposta é simples: porque queremos que o utilizador final possa expandir o tema fruity, modificar o ficheiro no seu tema local e carregar esse ficheiro modificado a partir do seu tema herdado. Para perceber, basta expandir o fruity e observar o tema expandido. O tema expandido nem sequer tem o ficheiro custom.css, pelo que será utilizado o do fruity. Mas, se o utilizador criar esse ficheiro no tema expandido (clicando em "Expandir" no Editor de temas), esse ficheiro será carregado a partir do seu tema.
Em geral:
se criar um tema de raiz sem expandir nenhum tema, utilize simplesmente a instrução add para adicionar os seus ficheiros CSS/JS. Muito simples.
se criar um tema que expande outro tema e não quiser que os utilizadores possam expandir os ficheiros CSS/JS do tema pai: não utilize a instrução add no seu manifesto. Os ficheiros continuarão a ser carregados a partir da configuração do tema pai.
se criar um tema que expande outro tema e quiser substituir um ficheiro do tema pai: utilize a palavra-chave replace (a palavra-chave add terá o mesmo resultado).
se criar um tema que expande outro tema, não substituir um determinado ficheiro CSS/JS, mas quiser que os utilizadores possam expandir esse ficheiro: utilize então a instrução "replace" no seu manifesto para esse ficheiro. Mesmo que não substitua o ficheiro, ao utilizar a palavra-chave replace no manifesto permite que o utilizador o faça, se assim o desejar.
Apenas este último caso exige um pouco de ginástica mental para ser compreendido; todos os outros casos são triviais.
Também pode registar ficheiros CSS e JS diretamente a partir do código twig. Esses ficheiros só serão carregados quando o ficheiro twig for solicitado. Se quiser que os utilizadores possam herdar esses ficheiros JS/CSS a partir do editor de temas, lembre-se de utilizar as funções Template:RegisterTemplateCssFile('my style.css') e Template:RegisterTemplateScript('my script.js'). Se não utilizar estas funções, o seu tema poderá funcionar, mas a herança ficará comprometida. A lógica é a mesma da função Template:Image('my picture.jpg')
A palavra-chave remove
A palavra-chave remove só está disponível desde a versão 3.14. Com ela, pode eliminar qualquer ficheiro CSS de qualquer pacote, mesmo dos principais. É utilizada no Material Premium Theme para eliminar os ficheiros da Awesome Bootstrap Checkbox:
<remove>awesome-bootstrap-checkbox/awesome-bootstrap-checkbox.css</remove>
Deve, por isso, utilizar exatamente a mesma sintaxe do ficheiro do pacote (ex.: "awesome-bootstrap-checkbox.css" sozinho, sem o caminho da pasta, não funcionaria). Encontrará a lista completa dos pacotes principais e dos seus ficheiros 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 forma de encontrar o nome exato a utilizar na tag remove é ativar o gestor de assets (desativando o modo debug ou definindo 'use_asset_manager'=>true no config). Assim, o caminho a utilizar será o que surge logo após a pasta aleatória na pasta 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" />
Ficheiros que não deve eliminar:
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, julgo)
em_javascript.js : necessário para todo o JavaScript do ExpressionScript
A secção de opções
Esta secção diz respeito às opções do seu tema. Será utilizada para preencher o campo "options" da tabela template_configuration como uma tabela JSON.
Mais informações
Algumas notas
NOTA: se editar o ficheiro XML de um tema, tem de desinstalar e voltar a instalar o tema para que as alterações sejam tidas em conta.
NOTA: para evitar isso, pode forçar a utilização do XML em vez da base de dados. No ficheiro config.php, ative o modo debug e retire o comentário de:
'force_xmlsettings_for_survey_rendering' => true, // Retire o comentário se quiser forçar a utilização do ficheiro XML em vez da base de dados (para facilitar o desenvolvimento de temas)
Tenha cuidado: tudo será carregado a partir do XML (incluindo as opções, etc.)
NOTA: se editar manualmente os ficheiros CSS/JS (sem utilizar o Editor de temas) e o modo debug estiver desativado, pode agora forçar a limpeza dos assets. Em "Configurações globais", separador "Geral", clique no botão "Limpar cache de assets".
NOTA: se eliminar a secção
