diff --git a/src/Bundle/ChillMainBundle/Resources/public/sass/_custom.scss b/src/Bundle/ChillMainBundle/Resources/public/sass/_custom.scss
index 3d7ce19af..0fe6bd846 100644
--- a/src/Bundle/ChillMainBundle/Resources/public/sass/_custom.scss
+++ b/src/Bundle/ChillMainBundle/Resources/public/sass/_custom.scss
@@ -157,16 +157,27 @@ dl.chill_view_data {
}
-blockquote.chill-user-quote {
+blockquote.chill-user-quote,
+div.chill-user-quote {
border-left: 10px solid $chill-yellow;
margin: 1.5em 10px;
padding: 0.5em 10px;
quotes: "\201C""\201D""\2018""\2019";
background-color: $chill-llight-gray;
-
-
- p { display: inline; }
-
+
+ blockquote {
+ margin: 1.5em 10px;
+ padding: 0.5em 10px;
+ }
+
+ blockquote:before {
+ color: #ccc;
+ content: open-quote;
+ font-size: 4em;
+ line-height: 0.1em;
+ margin-right: 0.25em;
+ vertical-align: -0.4em;
+ }
}
.chill-no-data-statement {
diff --git a/src/Bundle/ChillMainBundle/Templating/ChillMarkdownRenderExtension.php b/src/Bundle/ChillMainBundle/Templating/ChillMarkdownRenderExtension.php
new file mode 100644
index 000000000..8615150c3
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/Templating/ChillMarkdownRenderExtension.php
@@ -0,0 +1,56 @@
+
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+namespace Chill\MainBundle\Templating;
+
+use Twig\Extension\AbstractExtension;
+use Twig\TwigFilter;
+
+use Parsedown;
+
+/**
+ * Render markdown
+ *
+ */
+class ChillMarkdownRenderExtension extends AbstractExtension
+{
+ /**
+ *
+ * @var Parsedown
+ */
+ protected $parsedown;
+
+ public function __construct()
+ {
+ $this->parsedown = new Parsedown();
+ $this->parsedown->setSafeMode(true);
+ }
+
+ public function getFilters()
+ {
+ return [
+ new TwigFilter('chill_markdown_to_html', [$this, 'renderMarkdownToHtml'], [
+ 'is_safe' => [ 'html' ]
+ ])
+ ];
+ }
+
+ public function renderMarkdownToHtml($var)
+ {
+ return $this->parsedown->parse($var);
+ }
+}
diff --git a/src/Bundle/ChillMainBundle/Tests/Templating/ChillMarkdownRenderExtensionTest.php b/src/Bundle/ChillMainBundle/Tests/Templating/ChillMarkdownRenderExtensionTest.php
new file mode 100644
index 000000000..d95969b9d
--- /dev/null
+++ b/src/Bundle/ChillMainBundle/Tests/Templating/ChillMarkdownRenderExtensionTest.php
@@ -0,0 +1,76 @@
+
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+namespace Chill\MainBundle\Tests\Templating;
+
+use PHPUnit\Framework\TestCase;
+use Chill\MainBundle\Templating\ChillMarkdownRenderExtension;
+
+/**
+ * Test the service ChillMarkdownRenderExtension
+ *
+ * @internal we do not want to test the markdown transformation. We just want to
+ * test that the markdown is correctly transformed into html, and that the html
+ * is safe.
+ */
+class ChillMarkdownRenderExtensionTest extends TestCase
+{
+
+ private const SIMPLE_MARKDOWN = <<test
+Text.
+HTML;
+
+ private const UNAUTHORIZED_MARKDOWN = <<alert("ok");
+MD;
+
+ private const UNAUTHORIZED_HTML = <<<script>alert("ok");</script>
+HTML;
+
+ /**
+ * Test that the markdown input is transformed into html
+ */
+ public function testRendering()
+ {
+ $extension = new ChillMarkdownRenderExtension();
+
+ $this->assertEquals(self::SIMPLE_HTML,
+ $extension->renderMarkdownToHtml(self::SIMPLE_MARKDOWN));
+ }
+
+ /**
+ * Test that the output of the markdown content is sanitized
+ */
+ public function testSecurity()
+ {
+ $extension = new ChillMarkdownRenderExtension();
+
+ $this->assertEquals(self::UNAUTHORIZED_HTML,
+ $extension->renderMarkdownToHtml(self::UNAUTHORIZED_MARKDOWN));
+ }
+}
diff --git a/src/Bundle/ChillMainBundle/config/services/templating.yaml b/src/Bundle/ChillMainBundle/config/services/templating.yaml
index 0dfb92380..f9bd8d7fb 100644
--- a/src/Bundle/ChillMainBundle/config/services/templating.yaml
+++ b/src/Bundle/ChillMainBundle/config/services/templating.yaml
@@ -36,3 +36,7 @@ services:
- '@chill.main.user_repository'
tags:
- { name: 'chill.render_entity' }
+
+ Chill\MainBundle\Templating\ChillMarkdownRenderExtension:
+ tags:
+ - { name: twig.extension }
diff --git a/src/Bundle/ChillPersonBundle/Resources/views/Person/view.html.twig b/src/Bundle/ChillPersonBundle/Resources/views/Person/view.html.twig
index d9a0d8d31..45c8cd1ed 100644
--- a/src/Bundle/ChillPersonBundle/Resources/views/Person/view.html.twig
+++ b/src/Bundle/ChillPersonBundle/Resources/views/Person/view.html.twig
@@ -48,11 +48,9 @@ This view should receive those arguments:
{#{{ person.memo|nl2br }}
#}
-
+
+ {{ person.memo|chill_markdown_to_html }}
- {% apply markdown_to_html %}
- {{ person.memo }}
- {% endapply %}
{% endif %}
@@ -214,7 +212,7 @@ This view should receive those arguments:
{%- if chill_person.fields.email == 'visible' -%}
- {{ 'Email'|trans }} :
- - {% if person.email is not empty %}
{{ person.email|nl2br }}
{% else %}{{ 'No data given'|trans }}{% endif %}
+ - {% if person.email is not empty %}{{ person.email }}{% else %}{{ 'No data given'|trans }}{% endif %}
{%- endif -%}
{%- if chill_person.fields.phonenumber == 'visible' -%}
@@ -232,7 +230,15 @@ This view should receive those arguments:
{%- if chill_person.fields.contact_info == 'visible' -%}
- {{ 'Notes on contact information'|trans }} :
- - {% if person.contactInfo is not empty %}{{ person.contactInfo|nl2br }}{% else %}{{ 'No data given'|trans }}{% endif %}
+ -
+ {% if person.contactInfo is not empty %}
+
+ {{ person.contactInfo|chill_markdown_to_html }}
+
+ {% else %}
+ {{ 'No data given'|trans }}
+ {% endif %}
+
{%- endif -%}