From dabdbd6703aee0dbd8e258ad62b20317b714442a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Wr=C3=B3blewski?= Date: Sun, 12 Jan 2025 19:39:39 +0100 Subject: [PATCH] Add HTML column type --- docs/src/reference/types/column/html.md | 51 +++++++++++ src/Column/Type/HtmlColumnType.php | 44 ++++++++++ src/Resources/config/columns.php | 6 ++ src/Resources/views/themes/base.html.twig | 8 ++ tests/Unit/Column/Type/HtmlColumnTypeTest.php | 88 +++++++++++++++++++ 5 files changed, 197 insertions(+) create mode 100644 docs/src/reference/types/column/html.md create mode 100644 src/Column/Type/HtmlColumnType.php create mode 100644 tests/Unit/Column/Type/HtmlColumnTypeTest.php diff --git a/docs/src/reference/types/column/html.md b/docs/src/reference/types/column/html.md new file mode 100644 index 00000000..1eea35d2 --- /dev/null +++ b/docs/src/reference/types/column/html.md @@ -0,0 +1,51 @@ + + +# HtmlColumnType + +The [`HtmlColumnType`](https://github.com/Kreyu/data-table-bundle/blob/main/src/Column/Type/HtmlColumnType.php) represents a column with value displayed as HTML. + +## Options + +### `raw` + +- **type**: `bool` +- **default**: `true` + +Defines whether the value should be rendered as raw HTML. + +For example, if your column contains a string `Foo`: +- setting it to `true` will render the value as a bold text: **Foo** +- setting it to `false` will render the value as a plain text: `Foo` + +### `strip_tags` + +- **type**: `bool` +- **default**: `false` + +Defines whether the tags should be stripped. Internally uses the [`strip_tags`](https://twig.symfony.com/doc/3.x/filters/striptags.html) function. + +For example, if your column contains a string `Foo`: +- setting it to `true` will render the value as a simple text: Foo +- setting it to `false` will render the value as is: `Foo` + +### `allowed_tags` + +- **type**: `null`, `string` or `string[]` +- **default**: `null` + +Defines tags which should not be stripped if `strip_tags` is set to `true`, e.g. `

`. + +For example, if your column contains a string `Foo
`: +- setting it to `""` will render the value as: `Foo
` +- setting it to `"
"` will render the value as: `Foo
` +- setting it to `["", "
"]` will render the value as: `Foo
` +- setting it to `null` (by default) will render the value as: `Foo
` + +> [!WARNING] +> In Twig, this option is ignored if `strip_tags` option is set to `false`. + +## Inherited options + + diff --git a/src/Column/Type/HtmlColumnType.php b/src/Column/Type/HtmlColumnType.php new file mode 100644 index 00000000..ed7727ab --- /dev/null +++ b/src/Column/Type/HtmlColumnType.php @@ -0,0 +1,44 @@ +vars = array_replace($view->vars, [ + 'raw' => $options['raw'], + 'strip_tags' => $options['strip_tags'], + 'allowed_tags' => $options['allowed_tags'], + ]); + } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->define('raw') + ->default(true) + ->allowedTypes('bool') + ->info('Defines whether the value should be rendered as raw HTML.') + ; + + /* @see https://www.php.net/strip_tags */ + $resolver->define('strip_tags') + ->default(false) + ->allowedTypes('bool') + ->info('Defines whether the tags should be stripped. Internally uses the "strip_tags" function.') + ; + + /* @see https://www.php.net/strip_tags */ + $resolver->define('allowed_tags') + ->default(null) + ->allowedTypes('null', 'string', 'string[]') + ->info('Defines tags which should not be stripped if "strip_tags" is set to true, e.g. "

"') + ; + } +} diff --git a/src/Resources/config/columns.php b/src/Resources/config/columns.php index 1fe0dd4d..1a7436a8 100755 --- a/src/Resources/config/columns.php +++ b/src/Resources/config/columns.php @@ -18,6 +18,7 @@ use Kreyu\Bundle\DataTableBundle\Column\Type\DateTimeColumnType; use Kreyu\Bundle\DataTableBundle\Column\Type\EnumColumnType; use Kreyu\Bundle\DataTableBundle\Column\Type\FormColumnType; +use Kreyu\Bundle\DataTableBundle\Column\Type\HtmlColumnType; use Kreyu\Bundle\DataTableBundle\Column\Type\LinkColumnType; use Kreyu\Bundle\DataTableBundle\Column\Type\MoneyColumnType; use Kreyu\Bundle\DataTableBundle\Column\Type\NumberColumnType; @@ -109,6 +110,11 @@ ->tag('kreyu_data_table.column.type') ; + $services + ->set('kreyu_data_table.column.type.html', HtmlColumnType::class) + ->tag('kreyu_data_table.column.type') + ; + $services ->set('kreyu_data_table.column.type.date_time', DateTimeColumnType::class) ->tag('kreyu_data_table.column.type') diff --git a/src/Resources/views/themes/base.html.twig b/src/Resources/views/themes/base.html.twig index 41832ed7..e18c8e6f 100755 --- a/src/Resources/views/themes/base.html.twig +++ b/src/Resources/views/themes/base.html.twig @@ -495,6 +495,14 @@ {%- endblock %} +{% block column_html_value -%} + {% if strip_tags %} + {% set value = value|striptags(allowed_tags) %} + {% endif %} + + {{ raw ? value|raw : value }} +{%- endblock %} + {% block column_date_time_value -%} {% with { value: value ? value|date(format, timezone) : value } %} {{- block('column_text_value') -}} diff --git a/tests/Unit/Column/Type/HtmlColumnTypeTest.php b/tests/Unit/Column/Type/HtmlColumnTypeTest.php new file mode 100644 index 00000000..257ea445 --- /dev/null +++ b/tests/Unit/Column/Type/HtmlColumnTypeTest.php @@ -0,0 +1,88 @@ +createColumn(); + $columnValueView = $this->createColumnValueView($column); + + $this->assertTrue($columnValueView->vars['raw']); + } + + #[DataProvider('provideRawOption')] + public function testPassingRawOption(bool $raw): void + { + $column = $this->createColumn(['raw' => $raw]); + $columnValueView = $this->createColumnValueView($column); + + $this->assertEquals($raw, $columnValueView->vars['raw']); + } + + public static function provideRawOption(): iterable + { + yield 'true' => [true]; + yield 'false' => [false]; + } + + public function testDefaultStripTagsOption(): void + { + $column = $this->createColumn(); + $columnValueView = $this->createColumnValueView($column); + + $this->assertFalse($columnValueView->vars['strip_tags']); + } + + #[DataProvider('provideStripTagsOption')] + public function testPassingStripTagsOption(bool $stripTags): void + { + $column = $this->createColumn(['strip_tags' => $stripTags]); + $columnValueView = $this->createColumnValueView($column); + + $this->assertEquals($stripTags, $columnValueView->vars['strip_tags']); + } + + public static function provideStripTagsOption(): iterable + { + yield 'true' => [true]; + yield 'false' => [false]; + } + + public function testDefaultAllowedTagsOption(): void + { + $column = $this->createColumn(); + $columnValueView = $this->createColumnValueView($column); + + $this->assertNull($columnValueView->vars['allowed_tags']); + } + + #[DataProvider('provideAllowedTagsOption')] + public function testPassingAllowedTagsOption(null|string|array $allowedTags): void + { + $column = $this->createColumn(['allowed_tags' => $allowedTags]); + $columnValueView = $this->createColumnValueView($column); + + $this->assertEquals($allowedTags, $columnValueView->vars['allowed_tags']); + } + + public static function provideAllowedTagsOption(): iterable + { + yield 'null' => [null]; + yield 'string' => ['
']; + yield 'array of strings' => [['', '
']]; + } +}