Theme editor
From LimeSurvey Manual
(Redirected from The template editor)
Introduction
A survey theme controls how your survey looks to participants: the page layout, colours, fonts, logos and the styling of every question. Themes are built with Twig templates, CSS and JavaScript, and use Bootstrap 5 as their CSS framework.
Many common changes need no code at all. The logo, colours, fonts and several display settings can be changed with the theme options. Use the theme editor described on this page when you want to go further: add your own CSS or JavaScript, change the HTML of a page, or upload images and other files for your theme.
LimeSurvey comes with these core survey themes:
- Fruity TwentyThree (
fruity_twentythree): The default theme. - Bootstrap Vanilla (
vanilla): A plain base theme for developers who want to build their own Bootstrap-based theme. - Fruity (
fruity) and Bootswatch (bootswatch): Both extend Bootstrap Vanilla.
The look of individual question types is controlled by question themes, not by the survey theme. To change the HTML of a question type, create a question theme.
Before you start
To use the theme editor, you need the global Themes permission (see global permissions) or must be a superadministrator. Extending a theme needs the Create right, saving changes needs Update, and deleting a theme or resetting a file needs Delete.
Core themes cannot be edited: extend them
Core themes are updated together with LimeSurvey, so you cannot change them directly. To customize one, extend it. Extending creates a new user theme that inherits everything from its parent theme. Your theme only contains the files you change; everything else is taken from the parent theme. This way your theme still gets the bug fixes and improvements when LimeSurvey updates the parent theme.
To extend a theme, either:
- Go to Configuration > Themes, open the actions menu (⋯) at the end of the theme's row and click Extend, or
- Open the theme in the theme editor and click Extend in the toolbar.
Enter a name for the new theme. The theme editor then opens your new theme.
Where themes are stored
- Core themes:
themes/survey/in your LimeSurvey installation. - User themes (extended, uploaded or imported themes):
upload/themes/survey/.
You can also edit the files of a user theme directly on the server with your own editor. Make sure the web server can still read and write the files afterwards, so you can keep using the theme editor as well.
The theme editor
To open the theme editor, go to Configuration > Themes, open the actions menu (⋯) at the end of the theme's row and click Theme editor.
If you open a core theme, a note tells you that this is a standard theme and offers a link to extend it. You can look at its files and the preview, but you cannot save changes.
Toolbar
- Export: Downloads the theme as a ZIP file.
- Extend: Creates a new theme that inherits from this one (see above).
- Rename: Renames the theme. Only available for user themes.
- Delete: Deletes the theme. You cannot delete the theme that is set as the default theme.
- Theme: Switches the theme editor to another theme.
- Screen: Selects which survey page is shown in the preview and which files are listed for editing. The screens are: Question, Survey list, Welcome, Completed, Assessments, Error, Clear all, Load, Save, Registration, Print answers, Public statistics, PDF, Quotas exceeded, Navigation and Participant.
Editing files
The panels on the right list the files used by the selected screen:
- Screen part files: The Twig templates that build the page.
- JavaScript files
- CSS files
- Other files: Images, fonts and any other files of the theme.
Click a file name to open it in the editor. Files marked Inherited come from the parent theme. You can still edit an inherited file: the button below the editor then reads Copy to local theme and save changes, and saving copies the file into your theme with your changes. From then on your copy is used instead of the parent's file.
Files that belong to your theme have a Reset button. Reset deletes your copy, so the file from the parent theme is used again.
Uploading files
Use the upload field at the bottom of the Other files panel to add images, fonts or other files to your theme. Uploaded files are stored in the theme's files/ folder. By default you can upload images (gif, ico, jpg, jpeg, png) and these file types: css, js, map, json, eot, otf, ttf, woff, woff2, txt, md, xml, twig, lss, lsa, lsq and lsg. Your administrator can change these lists with the allowedthemeimageformats and allowedthemeuploads settings in config.php.
To show an uploaded image in a Twig file, use the image() function:
{{ image('./files/myfile.png', 'Alternative text for the picture', {"class": "myclass"}) }}
In CSS files, refer to uploaded files with a path relative to the css folder, for example url('../files/background.jpg').
Preview
Below the editor, a preview shows the selected screen with sample content. Use the Mobile, 640x480, 800x600, 1024x768 and Full buttons to check the page at different screen sizes.
The preview uses sample data and may not show every style exactly as a real survey does. Always check your changes in a real survey preview as well.
Importing and exporting themes
- To move a theme to another LimeSurvey installation, click Export in the theme editor toolbar. This downloads the theme as a ZIP file.
- To install a theme from a ZIP file, go to Configuration > Themes and click Upload & install.
How a theme is built
Theme folder
A theme folder contains:
- config.xml: The theme manifest: name, parent theme, CSS and JavaScript files, theme options and the screens shown in the theme editor.
- views/: The Twig templates.
layout_global.twigis the main layout for most survey pages. Other layouts are used for special pages, for examplelayout_survey_list.twigfor the public survey list andlayout_errors.twigfor error pages. Theviews/subviews/folder holds the smaller templates the layouts include. - css/ and scripts/: The theme's CSS and JavaScript files.
- files/: Images and other files used by the theme.
- options/: The page for the theme options.
Twig templates
The templates receive the survey data in the aSurveyInfo variable. To see everything it contains, turn on debug mode in application/config/config.php and add this line to the end of the body element in layout_global.twig:
{{ dump(aSurveyInfo) }}
For the functions you can use in templates, see Available Twig functions. For security reasons, templates run in a sandbox, so only these functions are available.
config.xml
The <files> section lists the CSS and JavaScript files that are loaded on survey pages:
<add>adds a file. If the parent theme already has a file with the same name, your file replaces it.<remove>stops a file of the parent theme from being loaded.
You do not need to list files from the parent theme again: they are loaded anyway.
LimeSurvey reads config.xml when a theme is installed and stores the settings in the database. After you change config.xml of an installed theme, go to Configuration > Themes, open the actions menu (⋯) of the theme and click Reset to reload the file.
Adding your own CSS and JavaScript
Every core theme has two files reserved for your own code:
- css/custom.css: Loaded after all other CSS files, so its rules override the theme's styles.
- scripts/custom.js: Loaded after the theme's own JavaScript.
When you extend a theme, these are the files to change. Add your CSS to custom.css instead of editing the theme's main CSS files, so your theme keeps getting updates of the parent theme.
To add more files, upload them and list them in the <files> section of your theme's config.xml. Use a file name that does not exist in the parent theme, otherwise your file replaces the parent's file:
<files>
<css>
<add>css/my-styles.css</add>
</css>
<js>
<add>scripts/my-script.js</add>
</js>
</files>
Survey pages are loaded with Ajax by default, so the browser does not do a full page load when a participant moves to the next page. Run your JavaScript on both the first page load and every Ajax page load:
$(document).on('ready pjax:scriptcomplete', function () {
// Your code here
});
Styling questions with CSS
All examples in this section go into your theme's custom.css file.
Page classes
The <html> and <body> elements carry classes you can use to style whole pages:
- html: The language code (for example
en) and the text direction (dir-ltrordir-rtl). - body: The name of the theme and of each parent theme (for example
fruity_twentythree), the font (for examplefont-ibm-sans), the language (for examplelang-en), andbrand-logowhen the logo is shown.
Question container classes
Each question is wrapped in an element with the class question-container. It also carries:
- The class of the question type (see the table below).
mandatory: The question is mandatory or soft mandatory.input-error: The answer did not pass the validation, or a mandatory question was not answered.missing: The question still has unanswered parts and the participant has already moved past it.ls-hiddenandls-irrelevant: The question is hidden by its condition.ls-hidden-attribute: The question is hidden by its "Always hide this question" setting.- Any classes entered in the question's CSS class(es) setting (under Display). Use this to style single questions.
For example, a mandatory List (radio) question that was not answered:
<div id="question123" class="row list-radio mandatory input-error question-container">
...
</div>
Question type classes
| Question type | Class | Type code |
|---|---|---|
| 5 point choice | .choice-5-pt-radio | 5 |
| Array | .array-flexible-row | F |
| Array (5 point choice) | .array-5-pt | A |
| Array (10 point choice) | .array-10-pt | B |
| Array (Increase/Same/Decrease) | .array-increase-same-decrease | E |
| Array (Numbers) | .array-multi-flexi | : |
| Array (Texts) | .array-multi-flexi-text | ; |
| Array (Yes/Uncertain/No) | .array-yes-uncertain-no | C |
| Array by column | .array-flexible-column | H |
| Array dual scale | .array-flexible-dual-scale | 1 |
| Date/Time | .date | D |
| Equation | .equation | * |
| File upload | .upload-files | | |
| Gender | .gender | G |
| Huge free text | .text-huge | U |
| Language switch | .language | I |
| List (dropdown) | .list-dropdown | ! |
| List (radio) | .list-radio | L |
| List with comment | .list-with-comment | O |
| Long free text | .text-long | T |
| Multiple choice | .multiple-opt | M |
| Multiple choice with comments | .multiple-opt-comments | P |
| Multiple numerical input | .numeric-multi | K |
| Multiple short text | .multiple-short-txt | Q |
| Numerical input | .numeric | N |
| Ranking | .ranking | R |
| Short free text | .text-short | S |
| Text display | .boilerplate | X |
| Yes/No | .yes-no | Y |
Classes for the parts of a question
Inside the question container, the answer area uses these classes. Some depend on the question's display settings: for example, Array (Numbers) uses different classes when it shows checkboxes instead of dropdowns.
| Class | Used for | Used by (examples) |
|---|---|---|
| .ls-answers | The element that holds all answer options | All question types |
| .answers-list | A list or row of answer options | List (radio), Multiple choice, Ranking, rows of most arrays |
| .subquestion-list, .questions-list | A list or table of subquestions | Arrays, Multiple short text, Multiple numerical input |
| .answer-item | One answer option or input | Almost all question types |
| .noanswer-item | The "No answer" option | Arrays, 5 point choice, List with comment |
| .question-item | A subquestion that is also an answer | Multiple choice, Multiple short text, Multiple numerical input |
| .radio-list | A list or row of radio buttons | List (radio), 5 point choice, List with comment, rows of radio arrays |
| .radio-array | A table of radio buttons | Array, Array (5 point choice), Array (10 point choice), Array (Increase/Same/Decrease), Array (Yes/Uncertain/No) |
| .radio-item | One radio button with its label | List (radio), 5 point choice, List with comment, radio arrays |
| .checkbox-list | A list of checkboxes | Multiple choice, Multiple choice with comments |
| .checkbox-array | A table of checkboxes | Array (Numbers) with checkbox layout |
| .checkbox-item | One checkbox with its label | Multiple choice, Multiple choice with comments, Array (Numbers) with checkbox layout |
| .checkbox-text-item | A checkbox with a text field | Multiple choice with comments |
| .comment-item | The comment field next to a checkbox | Multiple choice with comments |
| .text-list | A list of text inputs | Multiple short text, Multiple numerical input |
| .text-item | One text input | Short, long and huge free text, Multiple short text, Array (Texts) |
| .number-list, .numeric-item | Numeric inputs | Multiple numerical input, Numerical input |
| .number-array | A table of numeric inputs | Array (Numbers), Array (Texts) |
| .text-array | A table of text inputs | Array (Texts), Array (Numbers) |
| .dropdown-array, .dropdown-list, .dropdown-item | Tables, rows and cells with dropdowns | Array (Numbers), Array dual scale with dropdowns |
| .date-item | The date input | Date/Time |
| .upload-item | The file upload area | File upload |
| .answertext | The subquestion text in an array row | Arrays |
| .col-answers | The column of subquestion texts | Arrays |
| .ls-heading | The header row with the answer options | Arrays |
| .ls-odd, .ls-even | Alternating rows | Arrays |
| .ls-label-xs-visibility | A label that is only visible on small screens and to screen readers | Cells of arrays |
| .ls-input-group-extra | The prefix or suffix of an input | Short free text, Numerical input, Multiple short text, Multiple numerical input |
| .ls-js-hidden | Hidden when JavaScript is active | Array dual scale, List (radio) |
| .ls-no-js-hidden | Hidden when JavaScript is not active | Ranking |
| .ls-js-hidden-sr | Hidden when JavaScript is active, but still read by screen readers | Ranking |
no-anwser-item (with this spelling) instead of noanswer-item.For example, this is the HTML of a List (radio) question's answers:
<ul class="ls-answers answers-list radio-list list-unstyled" role="radiogroup">
<li id="javatbdQ123_S456" class="answer-item radio-item">
<input type="radio" value="A" name="Q123" id="answerQ123A">
<label for="answerQ123A" class="control-label radio-label">Option A</label>
</li>
...
</ul>
Validation and tip classes
Validation tips (such as "Choose one of the following answers" or "Please enter a number between 1 and 10") always have the class ls-em-tip. While the participant answers, LimeSurvey adds ls-em-success when the tip's rule is met and ls-em-error when it is not, so you can style the two states differently. Tips hidden with the question's Hide tip setting get the class hide-tip.
Each tip also has a class for its type:
| Class | Tip |
|---|---|
| .em_default | The default tip of the question type (for example "Choose one of the following answers") |
| .em_num_answers | Minimum or maximum number of answers |
| .em_value_range | Minimum or maximum value |
| .em_sum_range | Minimum or maximum sum of the values |
| .em_sum_equals | The values must add up to a given total |
| .em_value_integer | Only whole numbers are allowed |
| .em_numbers_only | Only numbers are allowed |
| .em_other_numbers_only | Only numbers are allowed in the "Other" field |
| .em_other_comment_mandatory | The "Other" option is selected but its text field is empty |
| .em_regex_validation | The answer must match the validation pattern |
| .em_q_fn_validation | The question validation equation |
| .em_sq_fn_validation | The subquestion validation equation |
Right-to-left (RTL) languages
For right-to-left languages, the <html> element has the class dir-rtl and the core themes load an RTL version of their main CSS file. Use .dir-rtl in your CSS for rules that only apply to right-to-left languages.
Tips & tricks
These recipes go into custom.css (or a Twig file, where noted) of a theme you extended from a core theme. In the examples, replace #c0392b with your own colour.
Change the colour of radio buttons and checkboxes
To use one of the colours that come with Fruity TwentyThree, select a Theme color in the theme options. The theme options also let you choose a different Check icon.
For any other colour, add CSS to custom.css. The core themes draw their own radio buttons and checkboxes instead of the browser's default ones, so changing the colour means changing these drawn elements.
Fruity TwentyThree:
.radio-item input[type=radio]:checked + label::before,
.checkbox-item input[type=checkbox]:checked + label::before {
border-color: #c0392b;
}
.radio-item input[type=radio]:checked + label::after {
background-color: #c0392b;
}
.checkbox-item input[type=checkbox]:checked + label::after {
color: #c0392b;
}
/* The text of the selected answer */
.radio-item input[type=radio]:checked + label,
.checkbox-item input[type=checkbox]:checked + label {
color: #c0392b;
}
Bootstrap Vanilla, Fruity and Bootswatch:
.radio-item input[type=radio]:checked + label::after {
background-color: #c0392b;
}
.checkbox-item input[type=checkbox]:checked + label::after {
background-color: #c0392b;
border-color: #c0392b;
color: #ffffff;
}
Keep enough contrast between the colour and the background, so that participants with low vision can still see which answers are selected.
Make radio buttons and checkboxes bigger
Bigger radio buttons and checkboxes are easier to tap on phones and tablets. This works in all core themes:
.radio-item label::before,
.radio-item label::after,
.checkbox-item label::before,
.checkbox-item label::after {
scale: 1.3;
}
In Fruity TwentyThree, also add some space between the radio buttons and the answer text:
.radio-item label {
padding-left: 14px;
}
Values up to about 1.4 work without further changes. With bigger values, the controls start to overlap the answer text and the edges of array rows on small screens, so you also need to add more space around them.
Change the colour of the progress bar
.progress-bar {
background-color: #c0392b;
}
Show content only in one language
The <body> element has a class with the current language, such as lang-en or lang-fr. You can use it to show different content per language, for example a help line in the footer. Add the text for each language to a Twig file of your theme, such as subviews/footer/footer.twig:
<div class="help-fr" lang="fr">Pour de l'aide, appelez le 000000</div>
<div class="help-en" lang="en">For help, please call 000000</div>
Then hide the text of the other languages in custom.css:
body:not(.lang-fr) .help-fr,
body:not(.lang-en) .help-en {
display: none;
}
Use a different logo per survey
You do not need a separate theme for each logo. Theme options can be set for a single survey: open the survey, click Theme options in the Survey settings menu and select a different Logo file. See Theme options.
Display a custom favicon
A favicon is the small icon shown in the browser tab and in bookmarks. The core themes show the file files/favicon.ico of the theme. To use your own icon, name it favicon.ico and upload it in the Other files panel of your extended theme. It replaces the icon of the parent theme.
Centre the logo in Fruity TwentyThree
Turn on the Logo in the theme options, then add this to custom.css:
#survey-nav .container-fluid {
position: relative;
}
#survey-nav .logo-container {
position: absolute;
left: 50%;
transform: translateX(-50%);
}
Add your own logo to the public survey list
The public survey list shows the LimeSurvey logo by default. To show your own logo:
- Extend Fruity TwentyThree and open your theme in the theme editor.
- Upload your logo in the Other files panel.
- Select the Survey list screen and open
layout_survey_list.twig. - Find the
<div>that contains{{ include('./ls_logo_svg.twig') }}. Replace this whole<div>, including the include line, with the code shown below these steps. - Click Copy to local theme and save changes.
- Go to Configuration > Global settings > General and select your theme as Theme for public survey list and error pages.
Use the name of your uploaded file, and your organisation's name as the alternative text:
{{ image('./files/mylogo.png', 'Name of your organisation', {"class": "img-fluid mx-auto d-block"}) }}
Change the file upload popup
(New in 7.6.0 ) The popup that opens when a participant uploads files in a file upload question is built from the Twig file survey/questions/answer/file_upload/modal-container.twig. The theme editor does not list this file. To change the popup, for example to add a help text, copy the file from application/views/ of your LimeSurvey installation into the views/ folder of your theme on the server (or into the ZIP file of your theme before you import it), keeping the folder structure: views/survey/questions/answer/file_upload/modal-container.twig. Then edit the copy. A question theme for the file upload question can contain its own copy as well. Keep the hidden input fields and the IDs in the file, since the upload script needs them.
Add a separator line to dual scale arrays
To draw a vertical line between the two scales of an Array dual scale question:
.array-flexible-dual-scale .header_separator,
.array-flexible-dual-scale .dual_scale_separator {
border-right: 1px solid #00a8e1;
}
JavaScript in questions
To run JavaScript on all pages of your surveys, put it in custom.js of your theme (see above).
You can also add a script to the text of a single question or group. LimeSurvey removes scripts from these texts unless the XSS filter is off for your user. The filter never applies to superadministrators. For other users, Filter HTML for XSS must be turned off in Configuration > Global settings > Security. Only do this if you trust everyone who can edit surveys. For details and examples, see Workarounds: Manipulating a survey at runtime using Javascript.