Registered elements / transforms do not work on first invocation
Closed this issue · 2 comments
A difficult one to explain, but I'm trying to set up Purify to "allow" <u>
tags, and transform them into <span style="text-decoration: underline">
.
After I've done what I think is required, it works, but not on the first call to Purify::clean() in a given PHP request cycle, e.g.
$ tinker
Psy Shell v0.9.3 (PHP 7.1.16 — cli) by Justin Hileman
>>> Purify::clean('<u>Foo</u>');
PHP Warning: Element 'u' is not supported (for information on implementing this, see the support forums) in /private/tmp/purify-test/vendor/ezyang/htmlpurifier/library/HTMLPurifier/HTMLDefinition.php on line 311
>>> Purify::clean('<u>Foo</u>');
=> "<span style="text-decoration:underline;">Foo</span>"
Whereas I'd expect:
$ tinker
Psy Shell v0.9.3 (PHP 7.1.16 — cli) by Justin Hileman
>>> Purify::clean('<u>Foo</u>');
=> "<span style="text-decoration:underline;">Foo</span>"
>>> Purify::clean('<u>Foo</u>');
=> "<span style="text-decoration:underline;">Foo</span>"
Steps to reproduce:
laravel new test-project
cd test-project
composer require stevebauman/purify
php artisan vendor:publish --provider="Stevebauman\Purify\PurifyServiceProvider"
- Edit
config/purify.php
and add "u" toHTML.Allowed
- Create
app/Providers/PurifyServiceProvider.php
as per https://gist.github.com/leewillis77/6c1fe0ad5448b1fae6b5412a2ee02502 - Edit
config/app.php
and addApp\Providers\PurifyServiceProvider::class
to the list of providers - Clear the purify cache (
rm -fr storage/purify/
) - Try
Purify::clean('<u>Foo</u>');
in a tinker session
[Sidenote, I'd be happy if I could get it just to allow as an alternative, but the same issue happens with that]
A bit late but I thought I'd add my solution.
Add the element to the definition
if ($def = $config->maybeGetRawHTMLDefinition()) {
$def->addElement('u', 'Inline', 'Inline', 'Common');
$def->info_tag_transform['u'] = new HTMLPurifier_TagTransform_Simple('span', 'text-decoration: underline;');
}
I really had a hard time getting this to work, but I finally tracked it down. The issue is the "tidy" functionality. <u>
(and in my case, <s>
) is being "fixed" into a styled span, even if you're trying to manually allow the tag (link to source).
Using the example service provider, this is what's in my setupDefinitions
:
$underline = $def->addElement('u', 'Inline', 'Inline', 'Common');
$underline->formatting = true;
$strike = $def->addElement('s', 'Inline', 'Inline', 'Common');
$strike->formatting = true;
And this is the key step:
config/purify.php
<?php
return [
...
'HTML.TidyLevel' => 'none',
...
];
If you don't disable Tidy, those tags will never work, since they're getting cleaned regardless of what your definition is.