WordPress 编辑器对 SVG 的支持一向是非常的不友好, 首先它不能上传 SVG 文件, 也不能自动的嵌入到内容中让它正常显示. 同时, 对内联 SVG 代码根本不识别, 会无情的将 SVG 代码自动删除.
在上一篇文章中我介绍了如何让 WordPress 支持上传 SVG 图片的方法, 似乎是部分的解决了这个问题. 最近在开发 "web 学习手册 (http://know.webhek.com)" 过程中遇到了大量的需要在 WordPress 可视化编辑器里使用内联 SVG(inline SVG) 代码的情况.
相信你也知道, WordPress 使用的是 TinyMCE 编辑器, 而 TinyMCE 编辑器仅对标准的 html5 标记进行支持, SVG 代码一律不识别, 当我在 WordPress 的编辑器了 "可视化" 和 "文本" 两个标签间切换时, 所有的 SVG 代码都被干净的删除.
网上有很多关于如何让 WordPress 的 TinyMCE 支持 SVG 的讨论, 在 TinyMCE 官方网站也找到了配置 TinyMCE 扩展标记 http://archive.tinymce.com/wiki.php/Configuration 的文档. 主要是三个配置点:, 和. 下面是网上拷贝的一段网友提供的配置 WordPress 编辑器的代码:
- add_filter('tiny_mce_before_init', 'vsl2014_filter_tiny_mce_before_init');
- function vsl2014_filter_tiny_mce_before_init( $options ) {
- if ( ! isset( $options['extended_valid_elements'] ) ) {
- $options['extended_valid_elements'] = 'svg';
- } else {
- $options['extended_valid_elements'] .= ',svg';
- }
- if ( ! isset( $options['valid_children'] ) ) {
- $options['valid_children'] = '+body[svg]';
- } else {
- $options['valid_children'] .= ',+body[svg]';
- }
- if ( ! isset( $options['custom_elements'] ) ) {
- $options['custom_elements'] = 'svg';
- } else {
- $options['custom_elements'] .= ',svg';
- }
- return $options;
- }
还有网友认为下面这样就可以了:
- function override_mce_options($initArray) {
- $opts = '*[*]';
- $initArray['valid_elements'] = $opts;
- $initArray['extended_valid_elements'] = $opts;
- return $initArray;
- }
- add_filter('tiny_mce_before_init', 'override_mce_options');
还有网友给出了下面的建议:
TinyMCE 删除 SVG 代码的原因是认为 < svg > 是空标记, 所以, 应该在 < svg > 代码里放入一点东西, 比如 , 或一句 "抱歉, 你的浏览器不支持 SVG"(在支持 SVG 的浏览器里这句话是不显示的.)
应该给 SVG 标签上添加一个 id 属性.
将 SVG 代码放入 < pre > 内
上面的这些建议单独使用似乎都不成功, 但每种建议都似乎能解决一部分问题. 经过反复的实验, 我最终找到了下面的方法, 能成功的让 SVG 在 WordPress 的 TinyMCE 编辑器里不被删除, 而且保存良好的格式.
首先在 function.PHP 里加入下面的 PHP 代码:
- /**
- * Add to extended_valid_elements for TinyMCE
- *
- * @param $init assoc. array of TinyMCE options
- * @return $init the changed assoc. array
- */
- function my_change_mce_options( $init ) {
- $ext = 'a[*],altglyph[*],altglyphdef[*],altglyphitem[*],animate[*],animatecolor[*],animatemotion[*],animatetransform[*],circle[*],clippath[*],color-profile[*],cursor[*],defs[*],desc[*],ellipse[*],feblend[*],fecolormatrix[*],fecomponenttransfer[*],fecomposite[*],feconvolvematrix[*],fediffuselighting[*],fedisplacementmap[*],fedistantlight[*],feflood[*],fefunca[*],fefuncb[*],fefuncg[*],fefuncr[*],fegaussianblur[*],feimage[*],femerge[*],femergenode[*],femorphology[*],feoffset[*],fepointlight[*],fespecularlighting[*],fespotlight[*],fetile[*],feturbulence[*],filter[*],font[*],font-face[*],font-face-format[*],font-face-name[*],font-face-src[*],font-face-uri[*],foreignobject[*],g[*],glyph[*],glyphref[*],hkern[*],line[*],marker[*],mask[*],metadata[*],missing-glyph[*],mpath[*],path[*],pattern[*],polygon[*],polyline[*],radialgradient[*],rect[*],script[*],set[*],stop[*],lineargradient[*],style[*],svg[*],switch[*],symbol[*],text[*],textpath[*],title[*],tref[*],tspan[*],use[*],view[*],vkern[*]';
- // Add to extended_valid_elements if it alreay exists
- if ( isset( $init['extended_valid_elements'] ) ) {
- $init['extended_valid_elements'] .= ',' . $ext;
- } else {
- $init['extended_valid_elements'] = $ext;
- }
- // Super important: return $init!
- return $init;
- }
- add_filter('tiny_mce_before_init', 'my_change_mce_options');
在上面的 WordPress 过滤器里, 我将所有的 SVG 标记元素都添加了上去(至于用通配符'*[*]'的方法, 我没有实验过, 有兴趣的朋友可以试试, 欢迎给出反馈.)
细心的朋友可能观察到, 上面的 SVG 标记名称全都改成了小写. 而很显然 SVG 官方规范里规定 SVG 标记名称的大小写是有意义的. 但我实验过, 使用驼峰式的 SVG 标记名称是不行的. 可能是 HTML 代码并不在意大小写的原因.
第二, 在 WordPress 的 TinyMCE 编辑器里, 将所有的 SVG 代码都用 < pre></pre > 包裹起来, 这样, TinyMCE 编辑器就能保持 SVG 代码的原有缩进格式.
第三, 在 < svg></svg > 代码里放入一点东西, 比如 , 或一句 "抱歉, 你的浏览器不支持 SVG":
- <svg>
- <rect> ... </rect>
抱歉, 你的浏览器不支持 SVG
</svg>
实施了上面的方法后, 我现在使用 WordPress 的 TinyMCE 编辑器, 在嵌入 SVG 代码后, 就像跟写入普通 HTML 代码一样, 不会被删除和情况. 我并没有深入的研究 TinyMCE 编辑器对 SVG 代码的处理机制, 上面的这些方法也只是治标不治本. 也许随着 WordPress 的升级或 TinyMCE 升级, 这些方法会失效.
如果你有更巧的方法, 请在评论里分享, 谢谢!
来源: http://www.webhek.com/post/wordpress-editor-support-inline-svg.html