I have found two imperfect but functional solutions, each with its own limitations.
Please note, before you can employ either of the solutions, you will need to enable SVG uploading to your page first (as WP does not allow it by default). You can do this by using a plugin like Safe SVG.
The solution I chose in the end actually doesn't require any jQuery at all. It involves using a popular WP plug-in called "Advanced Custom Fields" (or ACF) and adding some php to your templates. The second solution is one which I found in one of the SVG discussion threads posted by socki03 in a different question (which I happened to have asked); it uses a jQuery library called SVGinjector.
This solution is the one I chose to implement, and I found it in this discussion thread. It isn't ideal because you have to add some code explicitly to your templates, (instead of being able to add everything in in the WP dashboard). So, If you go this route, you should to know a bit about editing template files.
What the ACF solution does
Once you set-up the ACF plug-in appropriately and place the code in your template, you will field in your dashboard which you allows you to select an SVG file. It is great because that SVG is really a part of the page, which is modifyiable with CSS, and loads with all of the other elements early on.
How to implement it
- Install the ACF plugin.
Using the ACF-plugin, follow the steps to create an image field that returned the image URL.
2.1. go to the dashboard
2.2. select the custom fields section (it is part of the ACF plugin)
2.3. at the top of the page it says "Field Groups", select the "add new" button next to it.
2.4. Create the field
2.4.1. designate the "field name", and the select the appropriate options. You need to making sure to select the "image" for the "field type" option.
2.4.2. After you select "image" from the "field type" options, a new option, "Return URL", will appear. It is that option that is going to generate the code that will grab your images. Choose "Return URL"
3.Open the php file for the template you want to add the svg to.
Inside your php file, insert this code anywhere you want the SVG to appear: <?php echo file_get_contents( get_field( 'the_svg_field_name_you_designated' ) ); ?>
and save your file.
Go back to the WP dashboard, go to "pages", and navigate to the "edit" screen for the page you want the SVG to appear in. You should now have field with the "field name" you entered that will you to select an image.
Click on the button near the field name, it should then prompt you to navigate your files. Navigate to the SVG file you want to upload, and select it.
Click on "Update" to finalize the SVG insertion. You should now have SVGs that load as part of the page, which you can edit/stylize with CSS.
Pros:
The code that inserts the SVG executes as the page loads, so the SVG element is part of the foundations fo the page, rather than being "added-on" later (whic is the problem with the other solution).
Cons:
Because the SVG is called from a separate file, and not combined in any meaingful way with other code on the page, all of the classes must be manually inserted into the SVG file. That means if you want to have two different versions of the same SVG, with different classes, you have two use two different files. However, you can work around this limitation, and still use the same file for two differently styled SVGs, by editing the parent classes in the templages and then using those classes to stylize the two different files (e.g. .parentForStyle1 svg
and .parentForStyle2 svg
).
Also, with this method you have to modify your code a bit more, than in the other case, but it really isn't too bad.
This did what I wanted, in that it allowed me to add SVGs that are visible to the DOM and stylizable with CSS, but it has one problem. Because it uses an enqueued script, it doesn't run until after the page has loaded the other elements. As such, can cause weird shifts/blinks while the page loads and and after excutes.
What SVGinjector does
When implemented, SVGinjector:
- calls a separate SVG file as an img element;
- uses javascript to parse the SVG and inject the SVG as an inline element; visible to the DOM.
- allows the designer to employ CSS to stylize the individual SVG paths/elements.
- converts the
img
element to an svg
element, and combines any header info from the existing img
tag and the SVG-file into the SVG-tag.
How to implement it
- In your template file, add a class called
inject-me
to your img
element where you want to have the SVG drawn, and in the img tag link the SVG file to the img
using data-src
instead of src
. Here is the working code I put in my template file: <img class="funkyLogo inject-me" data-src="<?php echo $logoImg; ?>" alt="logo" />
enqueue the js script "svg-injector.min.js" (which is in the SVG injector .zip file) in your "functions.php", along with your custom js:
function mytheme_enqueue_front_page_scripts() {
if( is_front_page() )
{
wp_enqueue_script( 'myJq', "/js/jquery-1.10.2.min.js", array( 'jquery' ), null, true );
wp_enqueue_script( 'injectSVG', get_stylesheet_directory_uri() . '/js/svg-injector.min.js', array( 'jquery' ), null, true );
wp_enqueue_script( 'custom', get_stylesheet_directory_uri() . '/js/custom.js', array( 'jquery' ), null, true );
}
}
add_action( 'wp_enqueue_scripts', 'mytheme_enqueue_front_page_scripts' );
include the following code in your "custom.js" file
//For testing in IE8
if (!window.console){ console = {log: function() {}}; };
// Elements to inject
var mySVGsToInject = document.querySelectorAll('img.inject-me');
// Options
var injectorOptions = {
evalScripts: 'once',
pngFallback: 'assets/png',
each: function (svg) {
// Callback after each SVG is injected
if (svg) console.log('SVG injected: ' + svg.getAttribute('id'));
}
};
// Trigger the injection
SVGInjector(mySVGsToInject, injectorOptions, function (totalSVGsInjected) {
// Callback after all SVGs are injected
console.log('We injected ' + totalSVGsInjected + ' SVG(s)!');
});
Pros:
It is simple, uses an img tag, and it is easy to edit classes in templates
Cons:
the SVGs are drawn later in the page drawing process, and this can cause weird rendering effects/blinking/changes in the pages while loading. I am currently using customizer and have my SVG designated as my header logo. Maybe it is happening because data-src
tag is confusing Wordpress, so before the js for SVG runs, the theme temporarily shows the alt
designated text "logo" in the img
tag. If I remove the alt
text, the div is empty for about half a second before the SVG is injected, but this causes an odd and undesirable shifting of elements on the page during the injection.
Alternately, the issue might have to do with order in which js is execute when drawing the page. I have learned that enqueued js always runs after page loading, so the fact that this is controlled via js, at the end of the loading process is very likely what is causing the blink. If someone can suggest a solution for that uses SVG injector, but doesn't cause a blink, it would be nice to see it.