前提
我想使用HTML Purifier转换< body>标签为< div>标签,以保持< body>上的内联样式元素,例如< body style =“background:color#000000;”>您好.< / body>将转向< div style =“background:color#000000;”>您好.< / div>.我正在研究custom tag和TagTransform类的组合.
当前设置
在我的配置部分,我目前正在这样做:
$htmlDef = $this->configuration->getHTMLDefinition(true);
// defining the element to avoid triggering 'Element 'body' is not supported'
$bodyElem = $htmlDef->addElement('body', 'Block', 'Flow', 'Core');
$bodyElem->excludes = array('body' => true);
// add the transformation rule
$htmlDef->info_tag_transform['body'] = new HTMLPurifier_TagTransform_Simple('div');
……以及允许< body>它的样式(以及类和id)属性通过配置指令(它们是一个工作的大型列表的一部分,该列表被解析为HTML.AllowedElements和HTML.AllowedAttributes).
我已经关闭了定义缓存.
$config->set('Cache.DefinitionImpl', null);
不幸的是,在这个设置中,似乎HTMLPurifier_TagTransform_Simple从未调用其transform()方法.
HTML.Parent?
我认为罪魁祸首是我的HTML.Parent,设置为’div’,很自然,< div>不允许孩子< body>元件.但是,将HTML.Parent设置为’html’会让我知道:
ErrorException: Cannot use unrecognized element as parent
添加…
$htmlElem = $htmlDef->addElement('html', 'Block', 'Flow', 'Core');
$htmlElem->excludes = array('html' => true);
…摆脱该错误消息,但仍然没有转换标签 – 它被删除了.
添加…
$htmlElem = $htmlDef->addElement('html', 'Block', 'Custom: head?, body', 'Core');
$htmlElem->excludes = array('html' => true);
…也没有做任何事,因为它给我一个错误信息:
ErrorException: Trying to get property of non-object
[...]/library/HTMLPurifier/Strategy/FixNesting.php:237
[...]/library/HTMLPurifier/Strategy/Composite.php:18
[...]/library/HTMLPurifier.php:181
[...]
我现在仍在调整最后一个选项,试图找出我需要提供的确切语法,但如果有人知道如何根据他们自己过去的经验帮助我,我会欣赏正确方向的任何指示.
HTML.TidyLevel?
作为唯一可以想象的罪魁祸首,我的HTML.TidyLevel设置为“重”.我还没有尝试所有可能的星座,但到目前为止,这没有任何区别.
(因为我只是在接触它,所以我很难回想起我已经尝试过哪些星座,以免我在这里列出它们,但是由于我缺乏自信,我不会错过我做过的事情或误报了一些事情.我可能会在以后做完一些专门测试的时候编辑这个部分!)
完整配置
我的配置数据存储在JSON中,然后解析为HTML Purifier.这是文件:
{
"CSS" : {
"MaxImgLength" : "800px"
},
"Core" : {
"CollectErrors" : true,
"HiddenElements" : {
"script" : true,
"style" : true,
"iframe" : true,
"noframes" : true
},
"RemoveInvalidImg" : false
},
"Filter" : {
"ExtractStyleBlocks" : true
},
"HTML" : {
"MaxImgLength" : 800,
"TidyLevel" : "heavy",
"Doctype" : "XHTML 1.0 Transitional",
"Parent" : "html"
},
"Output" : {
"TidyFormat" : true
},
"Test" : {
"ForceNoIconv" : true
},
"URI" : {
"AllowedSchemes" : {
"http" : true,
"https" : true,
"mailto" : true,
"ftp" : true
},
"DisableExternalResources" : true
}
}
(URI.Base,URI.Munge和Cache.SerializerPath也设置了,但是我已经在这个粘贴中删除了它们.另外,HTML.Parent警告:如上所述,通常,这被设置为’div’.)
解决方法:
这段代码是您正在做的事情不起作用的原因:
/** * Takes a string of HTML (fragment or document) and returns the content * @todo Consider making protected */ public function extractBody($html) { $matches = array(); $result = preg_match('!<body[^>]*>(.*)</body>!is', $html, $matches); if ($result) { return $matches[1]; } else { return $html; } }
您可以使用%Core.ConvertDocumentToFragment将其关闭为false;如果你的其余代码是无bug的,它应该直接从那里开始工作.我不相信你的bodyElem定义是必要的.j