Skip to content

Instantly share code, notes, and snippets.

@dimobelov
Created August 28, 2017 11:41
Show Gist options
  • Save dimobelov/712f9e6d38ac71311fdae4fef3d3306b to your computer and use it in GitHub Desktop.
Save dimobelov/712f9e6d38ac71311fdae4fef3d3306b to your computer and use it in GitHub Desktop.
Function & Filter to Allow Inline SVG in WordPress TinyMCE Editor.
function allow_svg_in_tinymce( $init ) {
// NOTE: This doesn't take into account any security concerns regarding SVG.
// It doesn't remove potential vulnerable elements, etc. It just allows
// SVG, as is, assuming that the uploader is trusted. However, it would
// be easy to remove elements such as script if desired. Just remove from
// the array.
$svgElemList = array(
'a',
'altGlyph',
'altGlyphDef',
'altGlyphItem',
'animate',
'animateColor',
'animateMotion',
'animateTransform',
'circle',
'clipPath',
'color-profile',
'cursor',
'defs',
'desc',
'ellipse',
'feBlend',
'feColorMatrix',
'feComponentTransfer',
'feComposite',
'feConvolveMatrix',
'feDiffuseLighting',
'feDisplacementMap',
'deDistantLight',
'feFlood',
'feFuncA',
'feFuncB',
'feFuncG',
'feFuncR',
'feGaussianBlur',
'feImage',
'feMerge',
'feMergeNode',
'feMorphology',
'feOffset',
'fePointLight',
'feSpecularLighting',
'feSpotLight',
'feTile',
'feTurbulance',
'filter',
'font',
'font-face',
'font-face-format',
'font-face-name',
'font-face-src',
'font-face-url',
'foreignObject',
'g',
'glyph',
'glyphRef',
'hkern',
'image',
'line',
'lineGradient',
'marker',
'mask',
'metadata',
'missing-glyph',
'pmath',
'path',
'pattern',
'polygon',
'polyline',
'radialGradient',
'rect',
'script',
'set',
'stop',
'style',
'svg',
'switch',
'symbol',
'text',
'textPath',
'title',
'tref',
'tspan',
'use',
'view',
'vkern'
);
// extended_valid_elements is the list of elements that TinyMCE allows. This checks
// to make sure it exists, and then implodes the SVG element list and adds it. The
// format of each element is 'element[attributes]'. The array is imploded, and turns
// into something like '...svg[*],path[*]...'
if ( isset( $init['extended_valid_elements'] ) ) {
$init['extended_valid_elements'] .= ','.implode('[*],',$svgElemList).'[*]';
}
// return value
return $init;
}
add_filter('tiny_mce_before_init', 'allow_svg_in_tinymce');
@rhaglennydd
Copy link

This does not work if the SVG code is the sole child of the body element. Putting any other HTML/text before or after the SVG code will work, but if the SVG is all by itself it will be stripped. I tried to set the array element 'valid_children' to '+body[svg]'. Below is my code:

add_filter(
    'tiny_mce_before_init',
    function (array $settings): array {
        static $svg_elem_list = [
            'a',
            'altGlyph',
            'altGlyphDef',
            'altGlyphItem',
            'animate',
            'animateColor',
            'animateMotion',
            'animateTransform',
            'circle',
            'clipPath',
            'color-profile',
            'cursor',
            'defs',
            'desc',
            'ellipse',
            'feBlend',
            'feColorMatrix',
            'feComponentTransfer',
            'feComposite',
            'feConvolveMatrix',
            'feDiffuseLighting',
            'feDisplacementMap',
            'deDistantLight',
            'feFlood',
            'feFuncA',
            'feFuncB',
            'feFuncG',
            'feFuncR',
            'feGaussianBlur',
            'feImage',
            'feMerge',
            'feMergeNode',
            'feMorphology',
            'feOffset',
            'fePointLight',
            'feSpecularLighting',
            'feSpotLight',
            'feTile',
            'feTurbulance',
            'filter',
            'font',
            'font-face',
            'font-face-format',
            'font-face-name',
            'font-face-src',
            'font-face-url',
            'foreignObject',
            'g',
            'glyph',
            'glyphRef',
            'hkern',
            'image',
            'line',
            'lineGradient',
            'marker',
            'mask',
            'metadata',
            'missing-glyph',
            'pmath',
            'path',
            'pattern',
            'polygon',
            'polyline',
            'radialGradient',
            'rect',
            'script',
            'set',
            'stop',
            'style',
            'svg',
            'switch',
            'symbol',
            'text',
            'textPath',
            'title',
            'tref',
            'tspan',
            'use',
            'view',
            'vkern',
        ];
        
        $settings['extended_valid_elements'] =
            (($settings['extended_valid_elements'] ?? '') ?
                $settings['extended_valid_elements'] . ',' : '') .
            implode('[*],', $svg_elem_list) .
            '[*]';
        $settings['valid_children']          =
            (($settings['valid_children'] ?? '') ?
                $settings['valid_children'] . ',' : '') . '+body[svg]';
        
        return $settings;
    },
);

However, this does not solve the problem. Any ideas?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment