htmlpurifier icon indicating copy to clipboard operation
htmlpurifier copied to clipboard

How to set global attributes like microdata

Open adnedelcu opened this issue 4 years ago • 10 comments

I am trying to figure out how to add a global attribute setting. We would like to allow all microdata attributes itemscope, itemtype, etc.

I've looked through the code in HTMLDefinition.php and I've seen that if I add it to the info_global_attr property, it works, but I don't think this is the right approach considering the comment at line 319.

Can you please show me in the right direction? The forum at http://htmlpurifier.org/phorum is not working anymore.

adnedelcu avatar Oct 19 '20 10:10 adnedelcu

i am also in the same situation...i want to allow microdata attributes

<div class="schema-faq-code" itemscope="" itemtype="https://schema.org/FAQPage">
    <div itemscope="" itemprop="mainEntity" itemtype="https://schema.org/Question" class="faq-question">
        <h3 itemprop="name" class="faq-q">question</h3>
        <div itemscope="" itemprop="acceptedAnswer" itemtype="https://schema.org/Answer">
             <p itemprop="text" class="faq-a">answer</p>
        </div>
    </div>
</div>

it gets stripped into

<div class="schema-faq-code">
    <div class="faq-question">
        <h3 class="faq-q">jghjgh</h3>
        <div>
             <p class="faq-a">jghjghjghj</p>
        </div>
    </div>
</div>

antnb avatar Jun 28 '22 11:06 antnb

Almost 2 years later, and not a single response.

adnedelcu avatar Jun 28 '22 14:06 adnedelcu

http://htmlpurifier.org/docs/enduser-customize.html#addAttribute

demo.php

<?php

require_once '../ezyang/htmlpurifier/library/HTMLPurifier.auto.php';

$purifierconfig = HTMLPurifier_Config::createDefault();
$purifierconfig->set('CSS.AllowedProperties', array());

$def = $purifierconfig->getHTMLDefinition(true);

$def->addAttribute('div', 'itemtype', 'URI');
$def->addAttribute('div', 'itemprop', 'Enum#s:mainEntity,acceptedAnswer');
$def->addAttribute('div', 'itemscope', 'Bool');
$def->addAttribute('h3', 'itemprop', 'Enum#s:name');
$def->addAttribute('p', 'itemprop', 'Enum#s:text');

$purifier = new HTMLPurifier($purifierconfig);

$input='<div class="schema-faq-code" itemscope="dülüdülü" itemtype="https://schema.org/FAQPage" style="font-size:100px;nonsense">
    <div itemscope="" itemprop="mainEntity" itemtype="https://schema.org/Question" class="faq-question" id="hohoho">
        <h3 itemprop="name" class="faq-q" lalala="5">question</h3>
        <div itemscope="" itemprop="acceptedAnswer" itemtype="https://schema.org/Answer">
             <p itemprop="text" class="faq-a" onclick="alert(666)">answer</p>
        </div>
    </div>
</div>';

$output = $purifier->purify($input);

echo "Before:\n".$input."\nAfter:\n".$output."\n";

?>

Run php demo.php

Output:

Before:
<div class="schema-faq-code" itemscope="dülüdülü" itemtype="https://schema.org/FAQPage" style="font-size:100px;nonsense">
    <div itemscope="" itemprop="mainEntity" itemtype="https://schema.org/Question" class="faq-question" id="hohoho">
        <h3 itemprop="name" class="faq-q" lalala="5">question</h3>
        <div itemscope="" itemprop="acceptedAnswer" itemtype="https://schema.org/Answer">
             <p itemprop="text" class="faq-a" onclick="alert(666)">answer</p>
        </div>
    </div>
</div>
After:
<div class="schema-faq-code" itemscope="" itemtype="https://schema.org/FAQPage">
    <div itemscope="" itemprop="mainEntity" itemtype="https://schema.org/Question" class="faq-question">
        <h3 itemprop="name" class="faq-q">question</h3>
        <div itemscope="" itemprop="acceptedAnswer" itemtype="https://schema.org/Answer">
             <p itemprop="text" class="faq-a">answer</p>
        </div>
    </div>
</div>

peterdd avatar Jun 28 '22 20:06 peterdd

@peterdd I don't understand this last example in relation with the OP request. All microdata attributes (which are totally legit HTML5) can be added on any HTML tag, block or inline.

It's almost impracticable to maintain a code where we must add each attributes on each existing tag (and that list of tags evolves)… Is it really the only solution possible ? (argh)

rastapopougros avatar Sep 29 '22 10:09 rastapopougros

I found a way to set these attributes for specific elements : in this example span and h2

        seotext:
            config:
                HTML.Trusted: true
                HTML.Allowed: span[itemprop|itemscope|itemtype],h2[itemprop],h3            
            elements:
                span:
                    - Inline
                    - Inline
                    - Common
                    - itemprop: Text
                      itemscope: Text
                      itemtype: Text
                h2:
                    - Heading
                    - Inline
                    - Common
                    - itemprop: Text

Needed values for the parameters can be found in vendor/ezyang/htmlpurifier/library/HTMLPurifier/HTMLModule/Text.php

Starojitski avatar Nov 08 '22 14:11 Starojitski

To extend the answer from @Starojitski, to properly support the itemprop, itemscope, and itemtype on all elements, replace the span with a *.

The version I'm using that I saw works for a few more scenarios is this one:

HTML.Allowed: *[style|id|class|itemscope|itemtype|itemprop],div,b,strong,i,em,u,a[href|title],ul,ol,li,p[style],br,span[style],img[width|height|alt|src],h1,h2,h3,h4,h5,

adnedelcu avatar Nov 09 '22 09:11 adnedelcu

I was forced to look for a solution alternative to the one described by @adnedelcu because i was getting this message

The file "/var/www/app/symfony/app/config/config.yml" does not contain valid YAML: Reference 
"[itemscope|itemtype|itemprop],h2,h3" does not exist at line 2 
(near "HTML.Allowed: *[itemscope|itemtype|itemprop],h2,h3") 
in /var/www/app/symfony/app/config/config.yml 
(which is being imported from "/var/www/app/symfony/app/config/config_dev.yml").

It seems that the * breakes YAML. I wonder what i am doing wrong

Update

If i put single qoutes around the configuration: HTML.Allowed: '*[itemscope|itemtype|itemprop],h2,h3' i get another message User Warning: Global attribute '*' is not supported in any elements (for information on implementing this, see the support forums) I am using "exercise/htmlpurifier-bundle": "^4.1",

Starojitski avatar Nov 09 '22 10:11 Starojitski

I'm using a Laravel package over this one, but try to use double quotes " instead of '. Might fix your issue.

adnedelcu avatar Nov 09 '22 10:11 adnedelcu

Unfortunately double quotes don't change anything. Still getting User Warning: Global attribute '*' is not supported in any elements ...

Starojitski avatar Nov 09 '22 10:11 Starojitski

Check with your symfony package issue tracker. They might have something about this there. This package does not have that problem because I am using it as I wrote you, so I can only assume it's a Symfony package error.

adnedelcu avatar Nov 11 '22 08:11 adnedelcu