diff --git a/AI_HANDOVER.md b/AI_HANDOVER.md index bdf466b..5535213 100644 --- a/AI_HANDOVER.md +++ b/AI_HANDOVER.md @@ -657,4 +657,18 @@ Backend: - Fragerouting: `SurveyFlowService`, `SurveyConditionRepository` - Ergebnisdarstellung: `SurveyResultsViewService` - Exportlogik: `SurveyResultsExportService`, `SurveyResultsPdfService` -- Backend-Operationen und DCA-Verhalten: `tl_survey.php`, `SurveyDcaListener` \ No newline at end of file +- Backend-Operationen und DCA-Verhalten: `tl_survey.php`, `SurveyDcaListener` +## Ausbaustufe 3 (22.08.2026): Themenbereiche, Fragenreihenfolge, Rich-Text + +Führende Doku: Trilium → Kunden → Kinderschutzbund → Survey-Bundle → „12 Ausbaustufe 3“. + +- **Themenbereiche = fünfter Typ `section` in `tl_survey_content`** (keine eigene Tabelle). Ein Abschnitt ist eine Gliederungszeile ohne Antwortfeld; eine Frage gehört zum zuletzt vorangehenden Abschnitt in der Sortierung. Fragen vor dem ersten Abschnitt = „Allgemeine Fragen“. Abschnitte haben kein `published`/`mandatory`. +- `SurveyQuestionRepository`: `findAllBySurvey()` = alle Inhalte inkl. Abschnitte (Editor/Backend/Gliederung), `findQuestionsBySurvey()` = nur Fragen (Ablauf, Sprungziele, Zählung, Export). Zeilen mit leerem `type` (abgebrochene Backend-Entwürfe) werden überall ignoriert. `create(..., $insertAfterId)` fügt hinter einem Element ein und nummeriert neu (`renumber()`). +- `SurveyStructureService`: Outline (Positionsnummern nur für Fragen), Bereichszuordnung, Reader-Kontext („Frage n von m aus Bereich“, „Frage x von y insgesamt“), Gruppierung der Ergebnisse (`groupBySection`, sortierungsbasiert → funktioniert auch für Snapshots gelöschter Fragen). +- Frontend-Editor: gemeinsames Teil-Template `_survey_question_form.html.twig`; Buttons „Themenbereich hinzufügen“ und „Frage in ‚X‘ hinzufügen“ (Query `question=new&newType=section` bzw. `after=`, Hidden-Feld `insertAfter`). Drag&Drop sortiert Abschnitte wie Fragen; Add-Buttons werden bei ungespeicherter Reihenfolge ausgeblendet. +- Backend: `label_callback` rendert Abschnitte als Balken, Fragen eingerückt mit Positionsnummer; `oncreate_callback` setzt bei „Neu“ im Listenkopf (`mode=2`) die Sortierung ans Ende. Palette `section` = Typ + Titel. +- Reader: Einleitungstext nur bei der ersten Frage (`isFirstQuestion`); Kopfzeile mit Themenbereich; Ergebnisse/PDF/Excel nach Bereichen gegliedert (Excel: Bereichszeile 2, Fragetexte 3, Köpfe 4, Freeze `A5` – ohne Abschnitte bleibt das alte Layout). +- Rich-Text: `SurveyHtmlSanitizer` (symfony/html-sanitizer, Whitelist `p, br, ul, ol, li, strong, em, b, i`, keine Links) in Repositories + Backend-`save_callback`; Ausgabe über Twig-Filter `survey_rich` / `survey_has_text` / `survey_plain`. Frontend: Quill 2 lokal (`public/js/quill.min.js`, `survey-rich-text.js`, Toolbar fett/kursiv/Listen). Backend: `rte => 'tinyMCE_survey'` (`contao/templates/backend/be_tinyMCE_survey.html.twig`). +- Assets: Inline-CSS/JS aus `_survey_assets.html.twig` nach `public/css/survey-frontend.css` + `public/js/survey-frontend.js` ausgelagert; Chart.js lokal (`public/js/chart.umd.min.js`). +- Sicherheit: Editor-Debug-Zugang nur noch bei `kernel.debug=true` + lokalem Host (`$request->getHost()`); Range: `rangeMin/Max >= 0`, `rangeMax >= rangeMin`, `rangeStep >= 1` (FE + BE). +- Neue DB-Spalte: `tl_survey_answer.questionSection` (Snapshot des Bereichstitels). diff --git a/contao/dca/tl_survey.php b/contao/dca/tl_survey.php index 0b7b463..57a73d2 100644 --- a/contao/dca/tl_survey.php +++ b/contao/dca/tl_survey.php @@ -130,7 +130,8 @@ $GLOBALS['TL_DCA']['tl_survey'] = [ 'description' => [ 'label' => &$GLOBALS['TL_LANG']['tl_survey']['description'], 'inputType' => 'textarea', - 'eval' => ['rte' => 'tinyMCE', 'tl_class' => 'clr'], + 'eval' => ['rte' => 'tinyMCE_survey', 'tl_class' => 'clr'], + 'save_callback' => [[SurveyDcaListener::class, 'sanitizeRichText']], 'sql' => 'text NULL', ], 'internalNote' => [ diff --git a/contao/dca/tl_survey_answer.php b/contao/dca/tl_survey_answer.php index 265f79a..4990ddb 100644 --- a/contao/dca/tl_survey_answer.php +++ b/contao/dca/tl_survey_answer.php @@ -61,6 +61,9 @@ $GLOBALS['TL_DCA']['tl_survey_answer'] = [ 'questionSorting' => [ 'sql' => 'int(10) unsigned NOT NULL default 0', ], + 'questionSection' => [ + 'sql' => "varchar(255) NOT NULL default ''", + ], 'value' => [ 'label' => &$GLOBALS['TL_LANG']['tl_survey_answer']['value'], 'sql' => 'text NULL', diff --git a/contao/dca/tl_survey_content.php b/contao/dca/tl_survey_content.php index 09bab69..74155c5 100644 --- a/contao/dca/tl_survey_content.php +++ b/contao/dca/tl_survey_content.php @@ -13,6 +13,10 @@ $GLOBALS['TL_DCA']['tl_survey_content'] = [ 'onsubmit_callback' => [ [SurveyDcaListener::class, 'touchSurveyContentParent'], ], + 'oncreate_callback' => [ + // "Neu" im Listenkopf fügt in Contao oben ein – Fragen sollen immer ans Ende. + [SurveyDcaListener::class, 'placeNewContentAtEnd'], + ], 'onpalette_callback' => [ [SurveyDcaListener::class, 'resolveSurveyContentPalette'], ], @@ -38,7 +42,7 @@ $GLOBALS['TL_DCA']['tl_survey_content'] = [ ], 'label' => [ 'fields' => ['question', 'type'], - 'showColumns' => true, + 'label_callback' => [SurveyDcaListener::class, 'renderSurveyContentLabel'], ], 'operations' => [ 'edit' => [ @@ -73,6 +77,8 @@ $GLOBALS['TL_DCA']['tl_survey_content'] = [ 'text' => '{question_legend},type,question,description;{settings_legend},mandatory,published', 'range' => '{question_legend},type,question,description;{settings_legend},mandatory,published,rangeMin,rangeMax,rangeStep', 'choice' => '{question_legend},type,question,description;{settings_legend},mandatory,published,allowMultiple,answerOption1,answerOption2,answerOption3,answerOption4,answerOption5,answerOption6,answerOption7,answerOption8,answerOption9,answerOption10', + // Themenbereich: reine Gliederungszeile, kein Antwortfeld, kein Aktiv-/Pflicht-Flag. + 'section' => '{question_legend},type,question', ], 'fields' => [ 'id' => ['sql' => 'int(10) unsigned NOT NULL auto_increment'], @@ -84,7 +90,7 @@ $GLOBALS['TL_DCA']['tl_survey_content'] = [ 'type' => [ 'label' => &$GLOBALS['TL_LANG']['tl_survey_content']['type'], 'inputType' => 'select', - 'options' => ['yes_no_maybe', 'text', 'range', 'choice'], + 'options' => ['yes_no_maybe', 'text', 'range', 'choice', 'section'], 'reference' => &$GLOBALS['TL_LANG']['tl_survey_content']['types'], 'eval' => ['mandatory' => true, 'includeBlankOption' => true, 'submitOnChange' => true, 'chosen' => true, 'tl_class' => 'w50'], 'sql' => "varchar(32) NOT NULL default ''", @@ -98,7 +104,8 @@ $GLOBALS['TL_DCA']['tl_survey_content'] = [ 'description' => [ 'label' => &$GLOBALS['TL_LANG']['tl_survey_content']['description'], 'inputType' => 'textarea', - 'eval' => ['tl_class' => 'clr'], + 'eval' => ['rte' => 'tinyMCE_survey', 'tl_class' => 'clr'], + 'save_callback' => [[SurveyDcaListener::class, 'sanitizeRichText']], 'sql' => 'text NULL', ], 'mandatory' => [ @@ -211,12 +218,14 @@ $GLOBALS['TL_DCA']['tl_survey_content'] = [ 'label' => &$GLOBALS['TL_LANG']['tl_survey_content']['rangeMax'], 'inputType' => 'text', 'eval' => ['rgxp' => 'digit', 'tl_class' => 'w50'], + 'save_callback' => [[SurveyDcaListener::class, 'validateRangeMax']], 'sql' => 'int(10) NOT NULL default 10', ], 'rangeStep' => [ 'label' => &$GLOBALS['TL_LANG']['tl_survey_content']['rangeStep'], 'inputType' => 'text', 'eval' => ['rgxp' => 'digit', 'tl_class' => 'w50'], + 'save_callback' => [[SurveyDcaListener::class, 'validateRangeStep']], 'sql' => 'int(10) unsigned NOT NULL default 1', ], ], diff --git a/contao/languages/de/tl_survey_content.php b/contao/languages/de/tl_survey_content.php index 62001c1..36ea676 100644 --- a/contao/languages/de/tl_survey_content.php +++ b/contao/languages/de/tl_survey_content.php @@ -1,11 +1,12 @@ 'Ja-Nein-Frage', 'text' => 'Offene Frage', 'range' => 'Bewertungsfrage', 'choice' => 'Single/Multiple-Choice', + 'section' => 'Themenbereich (Abschnitt)', ]; $GLOBALS['TL_LANG']['tl_survey_content']['question'] = ['Frage', 'Titel bzw. Wortlaut der Frage.']; $GLOBALS['TL_LANG']['tl_survey_content']['description'] = ['Beschreibung', 'Optionale Zusatzbeschreibung zur Frage.']; @@ -29,4 +30,8 @@ $GLOBALS['TL_LANG']['tl_survey_content']['answerOption9'] = ['Antwort 9', 'Neunt $GLOBALS['TL_LANG']['tl_survey_content']['answerOption10'] = ['Antwort 10', 'Zehnte mögliche Antwort.']; $GLOBALS['TL_LANG']['tl_survey_content']['rangeMin'] = ['Kleinster Wert', 'Kleinster Wert des Schiebereglers.']; $GLOBALS['TL_LANG']['tl_survey_content']['rangeMax'] = ['Größter Wert', 'Größter Wert des Schiebereglers.']; -$GLOBALS['TL_LANG']['tl_survey_content']['rangeStep'] = ['Schrittweite', 'Abstand zwischen den möglichen Werten des Schiebereglers.']; \ No newline at end of file +$GLOBALS['TL_LANG']['tl_survey_content']['rangeStep'] = ['Schrittweite', 'Abstand zwischen den möglichen Werten des Schiebereglers.']; +$GLOBALS['TL_LANG']['tl_survey_content']['mandatoryBadge'] = 'Pflicht'; +$GLOBALS['TL_LANG']['tl_survey_content']['inactiveBadge'] = 'inaktiv'; +$GLOBALS['TL_LANG']['tl_survey_content']['rangeMaxBelowMin'] = 'Der größte Wert muss mindestens so groß sein wie der kleinste Wert.'; +$GLOBALS['TL_LANG']['tl_survey_content']['rangeStepInvalid'] = 'Die Schrittweite muss mindestens 1 sein.'; diff --git a/contao/languages/en/tl_survey_content.php b/contao/languages/en/tl_survey_content.php index ee40498..3b7305b 100644 --- a/contao/languages/en/tl_survey_content.php +++ b/contao/languages/en/tl_survey_content.php @@ -1,11 +1,12 @@ 'Yes-no question', 'text' => 'Open question', 'range' => 'Rating question', 'choice' => 'Single/multiple choice', + 'section' => 'Topic section', ]; $GLOBALS['TL_LANG']['tl_survey_content']['question'] = ['Question', 'Title or wording of the question.']; $GLOBALS['TL_LANG']['tl_survey_content']['description'] = ['Description', 'Optional additional description for the question.']; @@ -29,4 +30,8 @@ $GLOBALS['TL_LANG']['tl_survey_content']['answerOption9'] = ['Answer 9', 'Ninth $GLOBALS['TL_LANG']['tl_survey_content']['answerOption10'] = ['Answer 10', 'Tenth possible answer.']; $GLOBALS['TL_LANG']['tl_survey_content']['rangeMin'] = ['Minimum value', 'Smallest value of the slider.']; $GLOBALS['TL_LANG']['tl_survey_content']['rangeMax'] = ['Maximum value', 'Largest value of the slider.']; -$GLOBALS['TL_LANG']['tl_survey_content']['rangeStep'] = ['Step size', 'Distance between the possible slider values.']; \ No newline at end of file +$GLOBALS['TL_LANG']['tl_survey_content']['rangeStep'] = ['Step size', 'Distance between the possible slider values.']; +$GLOBALS['TL_LANG']['tl_survey_content']['mandatoryBadge'] = 'mandatory'; +$GLOBALS['TL_LANG']['tl_survey_content']['inactiveBadge'] = 'inactive'; +$GLOBALS['TL_LANG']['tl_survey_content']['rangeMaxBelowMin'] = 'The largest value must not be smaller than the smallest value.'; +$GLOBALS['TL_LANG']['tl_survey_content']['rangeStepInvalid'] = 'The step must be at least 1.'; diff --git a/contao/templates/backend/be_tinyMCE_survey.html.twig b/contao/templates/backend/be_tinyMCE_survey.html.twig new file mode 100644 index 0000000..76c7566 --- /dev/null +++ b/contao/templates/backend/be_tinyMCE_survey.html.twig @@ -0,0 +1,28 @@ +{# Reduzierter TinyMCE für Umfrage-Beschreibungen: nur Absätze, Listen, fett, kursiv. + Dieselbe Whitelist wie der Frontend-Editor (Quill) und der serverseitige Sanitizer. #} +{% extends '@Contao/be_tinyMCE.html.twig' %} + +{% block picker %}{% endblock %} + +{% block plugins %} +plugins: 'autosave lists', +{% endblock %} + +{% block valid_elements %} +valid_elements: 'p,br,ul,ol,li,strong/b,em/i', +forced_root_block: 'p', +{% endblock %} + +{% block menubar %} +menubar: false, +{% endblock %} + +{% block toolbar %} +toolbar: 'bold italic | bullist numlist | undo redo | removeformat', +{% endblock %} + +{% block custom %} +statusbar: false, +paste_block_drop: true, +paste_as_text: false, +{% endblock %} diff --git a/contao/templates/frontend/_survey_assets.html.twig b/contao/templates/frontend/_survey_assets.html.twig index 1da714c..43ea21e 100644 --- a/contao/templates/frontend/_survey_assets.html.twig +++ b/contao/templates/frontend/_survey_assets.html.twig @@ -1,1270 +1,2 @@ - - \ No newline at end of file + + diff --git a/contao/templates/frontend/_survey_question_form.html.twig b/contao/templates/frontend/_survey_question_form.html.twig new file mode 100644 index 0000000..1160991 --- /dev/null +++ b/contao/templates/frontend/_survey_question_form.html.twig @@ -0,0 +1,58 @@ +{# Gemeinsames Formular für Fragen und Themenbereiche (bestehend und neu). + Erwartet: form, formId, questionType, isNew (bool), dirtyHint (string), submitLabel (string), newQuestionContext (optional) #} +{% trans_default_domain 'messages' %} +{% set isSectionType = questionType == 'section' %} +{{ form_start(form, {attr: {class: 'survey-form-grid', id: formId, 'data-survey-dirty-form': '1', 'data-survey-question-form': '1'}}) }} + + {{ form_errors(form) }} + + {% if isNew and newQuestionContext|default(null) and newQuestionContext.insertAfter %} +
+ {% if newQuestionContext.sectionTitle %} + {{ 'survey.edit.insert_into_section'|trans({'%section%': newQuestionContext.sectionTitle}) }} + {% else %} + {{ 'survey.edit.insert_before_first_section'|trans }} + {% endif %} +
+ {% endif %} + + + + + + + + + {% if isNew %} +
+ + +
+ {% endif %} +{{ form_end(form) }} diff --git a/contao/templates/frontend/_survey_question_sort_assets.html.twig b/contao/templates/frontend/_survey_question_sort_assets.html.twig index 34ad532..27da7c6 100644 --- a/contao/templates/frontend/_survey_question_sort_assets.html.twig +++ b/contao/templates/frontend/_survey_question_sort_assets.html.twig @@ -1,119 +1,2 @@ - - \ No newline at end of file + diff --git a/contao/templates/frontend/_survey_rich_text_assets.html.twig b/contao/templates/frontend/_survey_rich_text_assets.html.twig new file mode 100644 index 0000000..c5857e5 --- /dev/null +++ b/contao/templates/frontend/_survey_rich_text_assets.html.twig @@ -0,0 +1,3 @@ + + + diff --git a/contao/templates/frontend/member_survey_edit.html.twig b/contao/templates/frontend/member_survey_edit.html.twig index 09e10b3..5bd878a 100644 --- a/contao/templates/frontend/member_survey_edit.html.twig +++ b/contao/templates/frontend/member_survey_edit.html.twig @@ -2,6 +2,7 @@ {% include '@Survey/frontend/_survey_assets.html.twig' %} {% include '@Survey/frontend/_survey_question_sort_assets.html.twig' %} +{% include '@Survey/frontend/_survey_rich_text_assets.html.twig' %} {% include '@Survey/frontend/_survey_branding.html.twig' %} @@ -49,6 +50,7 @@ {% set surveyMetaFormId = 'survey-meta-form' %} {% set newQuestionFormId = 'survey-question-form-new' %} {% set canQuestionReorder = canQuestionReorder|default(false) %} + {% set isLocked = structureLocked|default(false) %}
{% if backUrl %}{{ 'survey.edit.back_to_list'|trans }}{% endif %} @@ -61,7 +63,8 @@ {{ form_widget(surveyForm._token) }} {{ form_errors(surveyForm) }} - + +
{{ 'survey.edit.intro_hint'|trans }}
@@ -70,7 +73,7 @@
{% endif %} - {% if structureLocked|default(false) and not survey.published %} + {% if isLocked and not survey.published %}
{{ 'survey.edit.structure_locked'|trans }}
{% endif %} @@ -86,13 +89,25 @@ {% endif %} + + {% if not isLocked %} +
+ {{ 'survey.edit.add_section'|trans }} + {% if not hasSections %} + {{ 'survey.edit.sections_intro'|trans }} + {% endif %} +
+ {% endif %} +
- {% for question in questions %} + {% for entry in outline %} + {% set question = entry.model %} {% set questionAnchor = 'survey-question-' ~ question.id %} {% set isOpen = activeQuestionId == question.id %} {% set questionItemForm = questionForms[question.id]|default(null) %} {% set questionFormId = 'survey-question-form-' ~ question.id %} -
+ {% set isSection = entry.isSection %} +

{% if canQuestionReorder %} -

- {% if structureLocked|default(false) %} + {% if isLocked %}
-
- {{ ('survey.survey.question_type_' ~ question.type)|trans }} - {% if question.mandatory %}{{ 'survey.edit.mandatory_badge'|trans }}{% endif %} -
- {% if question.description|striptags|trim %}

{{ question.description|striptags|trim }}

{% endif %} + {% if isSection %} +

{{ 'survey.edit.section_locked_hint'|trans }}

+ {% else %} +
+ {{ ('survey.survey.question_type_' ~ question.type)|trans }} + {% if question.mandatory %}{{ 'survey.edit.mandatory_badge'|trans }}{% endif %} + {% if entry.sectionTitle %}{{ entry.sectionTitle }}{% endif %} +
+ {% if question.description|survey_has_text %}
{{ question.description|survey_rich }}
{% endif %} + {% endif %}
{% elseif questionItemForm %} {% set questionType = questionItemForm.type.vars.value ?: question.type ?: 'yes_no_maybe' %} - {{ form_start(questionItemForm, {attr: {class: 'survey-form-grid', id: questionFormId, 'data-survey-dirty-form': '1'}}) }} - - {{ form_errors(questionItemForm) }} - - - -
- - - - -
- - - - {{ form_end(questionItemForm) }} + {% include '@Survey/frontend/_survey_question_form.html.twig' with { + form: questionItemForm, + formId: questionFormId, + questionType: questionType, + isNew: false, + dirtyHint: 'survey.edit.dirty_question'|trans, + submitLabel: 'survey.edit.save_this_question'|trans + } only %}
- +
- +
@@ -181,12 +183,25 @@
+ + {% if entry.isLastInSection and not isLocked and (entry.sectionId > 0 or hasSections) %} + + {% endif %} {% else %}
{{ 'survey.edit.no_questions'|trans }}
{% endfor %} - {% if not (structureLocked|default(false)) %} -
+ {% if not isLocked %} + {% set newType = newQuestionContext.type|default('yes_no_maybe') %} +

@@ -203,50 +218,21 @@
{% if newQuestionForm %} - {% set questionType = newQuestionForm.type.vars.value ?: 'yes_no_maybe' %} - {{ form_start(newQuestionForm, {attr: {class: 'survey-form-grid', id: newQuestionFormId, 'data-survey-dirty-form': '1'}}) }} - - {{ form_errors(newQuestionForm) }} - - - -
- - - - -
- - - -
- - -
- {{ form_end(newQuestionForm) }} + {% set questionType = newQuestionForm.type.vars.value ?: newType %} + {% include '@Survey/frontend/_survey_question_form.html.twig' with { + form: newQuestionForm, + formId: newQuestionFormId, + questionType: questionType, + isNew: true, + newQuestionContext: newQuestionContext, + dirtyHint: 'survey.edit.dirty_new_question'|trans, + submitLabel: (questionType == 'section' ? 'survey.edit.save_new_section' : 'survey.edit.save_new_question')|trans + } only %} {% endif %}

- {% endif %} + {% endif %}
@@ -271,4 +257,4 @@ {% endif %} - \ No newline at end of file + diff --git a/contao/templates/frontend/show_survey.html.twig b/contao/templates/frontend/show_survey.html.twig index 1700ca8..2cb28b7 100644 --- a/contao/templates/frontend/show_survey.html.twig +++ b/contao/templates/frontend/show_survey.html.twig @@ -13,13 +13,22 @@ {% if errorMessage %}
{{ errorMessage }}
{% elseif survey %} + {% set showIntro = isFirstQuestion|default(false) and not isComplete %}

{{ survey.title|striptags|trim }}

{% if isPreview %}{{ 'survey.survey.preview_badge'|trans }}{% endif %} {% if progress.total > 0 %}{{ progress.current }}/{{ progress.total }}{% endif %}
-

{{ (survey.description|striptags|trim) ?: 'survey.survey.default_description'|trans }}

+ + {# Der Einleitungstext erscheint nur auf der ersten Seite. #} + {% if showIntro %} + {% if survey.description|survey_has_text %} +
{{ survey.description|survey_rich }}
+ {% else %} +

{{ 'survey.survey.default_description'|trans }}

+ {% endif %} + {% endif %} {% if isPreview %}
{{ 'survey.survey.preview_notice'|trans }}
@@ -48,9 +57,16 @@
{% elseif question %}
-
{{ 'survey.survey.question_progress'|trans({'%current%': progress.current}) }}
+ {% if progress.sectionTitle %} +
+ {{ 'survey.survey.section_kicker'|trans({'%number%': progress.sectionNumber, '%count%': progress.sectionCount}) }} + {{ progress.sectionTitle }} + {{ 'survey.survey.section_progress'|trans({'%current%': progress.sectionCurrent, '%total%': progress.sectionTotal, '%section%': progress.sectionTitle}) }} +
+ {% endif %} +
{{ 'survey.survey.overall_progress'|trans({'%current%': progress.current, '%total%': progress.total}) }}

{{ question.question|striptags|trim }}

- {% if question.description|striptags|trim %}

{{ question.description|striptags|trim }}

{% endif %} + {% if question.description|survey_has_text %}
{{ question.description|survey_rich }}
{% endif %} {{ form_start(surveyForm, {attr: {class: 'survey-form-grid', id: 'survey-answer-form-' ~ question.id}}) }} @@ -113,4 +129,4 @@
{% endif %} {% endif %} - \ No newline at end of file + diff --git a/contao/templates/frontend/show_survey_results.html.twig b/contao/templates/frontend/show_survey_results.html.twig index 16e79c6..4f40f2c 100644 --- a/contao/templates/frontend/show_survey_results.html.twig +++ b/contao/templates/frontend/show_survey_results.html.twig @@ -22,7 +22,11 @@ {{ 'survey.results.questions'|trans({'%count%': questionResults|length}) }} -

{{ (survey.description|striptags|trim) ?: 'survey.results.no_description'|trans }}

+ {% if survey.description|survey_has_text %} +
{{ survey.description|survey_rich }}
+ {% else %} +

{{ 'survey.results.no_description'|trans }}

+ {% endif %} {% if downloadUrl or pdfDownloadUrl %}
@@ -37,7 +41,16 @@
+ {% set previousSectionId = null %} {% for question in questionResults %} + {% set sectionId = question.section.id|default(0) %} + {% if hasSections|default(false) and sectionId != previousSectionId %} +
+ {{ 'survey.results.section_kicker'|trans }} +

{{ question.section.title|default('') ?: 'survey.results.section_default'|trans }}

+
+ {% set previousSectionId = sectionId %} + {% endif %}

{{ question.question|striptags|trim }}

@@ -47,8 +60,8 @@ {% endif %}
- {% if question.description|striptags|trim %} -

{{ question.description|striptags|trim }}

+ {% if question.description|survey_has_text %} +
{{ question.description|survey_rich }}
{% endif %}
@@ -132,7 +145,7 @@ {% endif %} - +