Font Awesome SVG

Icons in Chap theme

By default Semantic UI includes all Font Awesome icons using a font file (~75kb) and maps the icons to use more natural/semantic names with (~35kb) additional CSS rules. This implementation brings with it a couple of issues:

Large asset overhead even when only using a few icons
AMP pages can’t use Semantic UI Font Awesome font files so Semantic UI icon names need to be converted back to original Font Awesome names on the fly
Icon font file cannot ensure that anything is visible during webfont load
Hard to maintain availability of latest Font Awesome icons

To solve these issues Chap theme includes an option to use SVG icons instead of the default implementation.

SVG icons can be enabled by setting the Chap Theme -> Themes -> Icon to Font Awesome SVG.

Advantages

No need for icon font or mapping CSS
Only load the icons that are used on the page
Same implementation on AMP and non-AMP pages
Icons are not render-blocking and become visible as the page is loaded
Possibility to upgrade to Font Awesome Pro icon set

Tradeoffs

Possible inconsistencies, misalignments or bugs due to major rework of the icon system
Requires filesystem calls, but only the first time the icon is rendered, after that it is retrieved from cache
Can no longer use gradient colors on icons
[chap-embed] can only use 1 predefined play icon
Old icons in Gutenberg editor will work, but need to be reassigned to a SVG icon to display accurately in the editor

Overall the SVG implementation is more modern, faster and recommended. It may become the default Icon theme of the theme at some point in the future.

Chap Font Awesome SVG plugin

When the Font Awesome SVG icon theme is enabled you will be prompted to install an accompanying plugin to handle everything related to retrieving, displaying and caching the icons.

By default all the available icons in SVG format will be provided by the plugin from the /wp-content/plugins/chap-fa-svg/cfs-icons folder. How ever you can copy this directory to your child theme folder /wp-content/themes/chap-child/cfs-icons to use that instead. This allows you to modify the icons, add new ones, new types or sets, such as Font Awesome Pro or some other compatible SVG icon set.

The cfs-icons folder contains subfolders of different Font Awesome icon types – brands, regular and solid.

When adding custom icons you should add a new folder for it, not put them directly in the root directory.

Icons can be referred to by their type folder name and file name without extension combined, for example: solid/home, brands/amazon, regular/arrow-alt-circle-left.

Shortcodes

When this plugin is installed, icon shortcode should still work normally, in a backwards compatible manner:

Shortcode
<icon home />

This works because the plugin provides functionality for remapping the icon name home to it’s SVG equivalent solid/home, or even if the Semantic UI name is completely different, such as emergency -> solid/ambulance.

How ever, the plugin can also utilize the svg attribute of the icon, providing a direct path to the icon:

Shortcode
<icon svg="solid/home" />

This is a better alternative because it requires no processing time to determine the icon location.

Blocks

Font Awesome icon picker in Gutenberg block editor using react-select

When this plugin is installed, the icon picker used in Gutenberg blocks will be replaced with a picker that displays SVG icons. The icons are retrieved using AJAX calls and cached in your local storage.

If you had any content with icons prior to switching to Font Awesome SVG icon theme the editor will display a placeholder icon (since there is no icon font file loaded anymore) and suggest the alternative SVG version to be applied.

Content filter

Even if you don’t update your old content to use SVG icons in the block editor they will still be converted to SVG on the front end. The plugin applies a the_content filter to provide this backwards compatibility.

This filter can be turned off from Chap Theme -> Font Awesome SVG -> Settings -> Backwards compatibility if you no longer use any old icons in your content.

Templates

In theme template files icons are no longer rendered as plain HTML:

HTML
<i class="home icon" aria-hidden="true"></i>

But instead are rendered using a helper function:

PHP
<?php Chap\Icon\render('home'); ?>

This allows for the seamless transition between SVG and non-SVG icon themes.

You can also retrieve the icon markup as a string:

PHP
<?php 
...
$icon = Chap\Icon\get('home');
$menu_item_text .= ' ' . $icon;

Cache

SVG icon markup, Semantic UI to Font Awesome icon name mapping and icons in block editor are all cached for quick lookup.

Under Chap Theme -> Font Awesome SVG you can clear these caches if you’ve changed your icon set, or simply have a lot of old icons in the cache that are no longer used in your content.

Chap SVG icon cache

If needed, caching can be disabled by adding this line to your wp-config.php:

PHP
define('CHAP_SVG_CACHE', false);

FileSystem

Before an icon can be cached it needs to be retrieved from the filesystem. For filesystem calls WP FileSystem API is used. This works for most WordPress setups that have direct filesystem access.

If your filesystem requires credentials for any operation then the plugin may not work properly. You should try resolving your filesystem issues. Or alternatively you can override the Chap\FA\cfs_fs function to perform filesystem operations differently.

PHP
<?php
namespace Chap\FA;
...
/**
 * Pluggable FileSystem wrapper for retrieving icons.
 *
 * @param string $func FileSystem operation (exists|get_contents).
 * @param string $path Path to to perform perform operations on.
 * @return mixed
 */
if(!function_exists(__NAMESPACE__ . '\\cfs_fs')):
	function cfs_fs($func, $path) {
		if(validate_file($path) !== 0) {
			return;
		}
		if(!function_exists('WP_Filesystem')) {
			require_once ABSPATH . 'wp-admin/includes/file.php';
		}
		\WP_Filesystem();
		global $wp_filesystem;
		switch($func) {
			case 'exists':
				return $wp_filesystem->exists($path);
			case 'get_contents':
				return $wp_filesystem->get_contents($path);
		}
	}
endif;

The function is pluggable so if you define it somewhere before the plugin is executed you can override it. A possible place for doing so could be a Must Use plugin:

PHP
/wp-content/mu-plugins/cfs-fs.php
<?php

namespace Chap\FA;

/**
 * Use PHP filesystem functions.
 */
function cfs_fs($func, $path) {
	if(validate_file($path) !== 0) {
		return;
	}
	switch($func) {
		case 'exists':
			return file_exists($path);
		case 'get_contents':
			return file_get_contents($path);
	}
}

Security

SVGs are considered a security risk for WordPress because they can be manipulated to do a lot more than displaying a vector graphic. In Chap Font Awesome SVG plugin icons are passed through a strict wp_kses() ruleset to ensure only the markup required to display the icon is rendered:

PHP
<?php
/**
 * WP_KSES configuration for a SVG icon.
 */
if(!defined('CHAP_SVG_ICON_KSES')) {
	define('CHAP_SVG_ICON_KSES', [
		'span' => [
			'class' => true,
		],
		'svg' => [
			'style' => [
				'width' => true,
				'height' => true,
			],
			'viewbox' => true,
			'xmlns' => true,
			'xmlns:xlink' => true,
		],
		'path' => [
			'd' => true,
		],
	]);
}

You can define your own version of this constant in wp-config.php if you need more relaxed rules.

Icon names are specified in relation to the cfs-icons directory and include the type folder as well as the icon file name without extension, such as solid/home. To prevent any sort of directory traversal attack by a user with editor privileges, such as solid/home/../../../vulnerable-svg-file, the given name is verified with validate_file() function that is built into WordPress.

Summary

For best performance, latest icons and a unified icon set for AMP and non-AMP pages you should switch over to Font Awesome SVG icon theme from Chap Theme -> Themes -> Icon. It’s designed to be backwards compatible so you won’t need to go change all your content to use the new method.

If the change doesn’t suit you it’s possible to switch back to Font Awesome 4.7 or Font Awesome 5.0 icon themes. When reverting back, any blocks that you created that use SVG icons may become invalid but should be easily fixable using the Attempt Block Recovery feature.