“Wordpress Way” | article demonstrating what / why + fontawesome *

RESOURCES

  • ADDING FONTAWESOME MANUALLY
  • https://fontawesome.com/docs/web/use-with/wordpress/install-manually
  • Set up a Kit
    First we’ll lay a foundation with this function that you’ll call with your Kit embed code. Copy and paste this into your functions.php
  • 
    /**
     * Font Awesome Kit Setup
     *
     * This will add your Font Awesome Kit to the front-end, the admin back-end,
     * and the login screen area.
     */
    if (! function_exists('fa_custom_setup_kit') ) {
      function fa_custom_setup_kit($kit_url = '') {
        foreach ( [ 'wp_enqueue_scripts', 'admin_enqueue_scripts', 'login_enqueue_scripts' ] as $action ) {
          add_action(
            $action,
            function () use ( $kit_url ) {
              wp_enqueue_script( 'font-awesome-kit', $kit_url, [], null );
            }
          );
        }
      }
    }
    
  • Next, you’ll need to add the following code, also to your functions.php, replacing the yourkitcode.js with your real Kit token, which you can find in your Kit settings.
  • 
    fa_custom_setup_kit('https://kit.fontawesome.com/yourkitcode.js');
    


Wordpress Way

This article give a good example of what is meant by the wordpress way - why you should use it - what it means -

(in addition to a good aon aboutr font awesome)

 

https://wordpress.stackexchange.com/questions/317035/how-to-add-crossorigin-and-integrity-to-wp-register-style-font-awesome-5/319773#319773

 

 

I am upgrading Font Awesome 4 to version 5 which introduces both integrity and crossorigin attributes to the <link rel="stylesheet"> markup.

Currently, I am using:

wp_register_style('FontAwesome', 'https://example.com/font-awesome.min.css', array(), null, 'all' );
wp_enqueue_style('FontAwesome');

Which outputs as:

<link rel="stylesheet" id="FontAwesome-css" href="https://example.com/font-awesome.min.css" type="text/css" media="all" />

With Font Awesome 5 it introduces two new attributes and values (integrity and crossorigin) e.g:

<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU" crossorigin="anonymous">

So I need to find out how I can add both the integrity and crossorigin to wp_register_style, I have tried but my attempts to use wp_style_add_data have failed, it would seem that this method only supports conditional, rtl and suffix, alt and title.

Add a comment

 

style_loader_tag style_loader_tag is an official WordPress API, see the documentation: https://developer.wordpress.org/reference/hooks/style_loader_tag/

apply_filters( 'style_loader_tag', $html, $handle, $href, $media ) Filters the HTML link tag of an enqueued style.

First enqueue your stylesheet, see documentation: https://developer.wordpress.org/reference/functions/wp_enqueue_style/

wp_enqueue_style( 'font-awesome-5', 'https://use.fontawesome.com/releases/v5.5.0/css/all.css', array(), null );

The $handle is 'font-awesome-5' I do null so that there is no version number. This way it will be cached.

Simple str_replace A simple str_replace is enough to achieve what you want, see example below

function add_font_awesome_5_cdn_attributes( $html, $handle ) {
    if ( 'font-awesome-5' === $handle ) {
        return str_replace( "media='all'", "media='all' integrity='sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU' crossorigin='anonymous'", $html );
    }
    return $html;
}
add_filter( 'style_loader_tag', 'add_font_awesome_5_cdn_attributes', 10, 2 );

Add different atributes Below an example to add different atributes to (multiple) different stylesheets

function add_style_attributes( $html, $handle ) {

    if ( 'font-awesome-5' === $handle ) {
        return str_replace( "media='all'", "media='all' integrity='sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU' crossorigin='anonymous'", $html );
    }

    if ( 'another-style' === $handle ) {
        return str_replace( "media='all'", "media='all' integrity='blajbsf' example", $html );
    }

    if ( 'bootstrap-css' === $handle ) {
        return str_replace( "media='all'", "media='all' integrity='something-different' crossorigin='anonymous'", $html );
    }

    return $html;
}
add_filter( 'style_loader_tag', 'add_style_attributes', 10, 2 );

Add attributes to all styles Below an example to add the same atributes to more than one stylesheet

function add_attributes_to_all_styles( $html, $handle ) {

        // add style handles to the array below
        $styles = array(
            'font-awesome-5',
            'another-style',
            'bootstrap-css'
        );

        foreach ( $styles as $style ) {
            if ( $style === $handle ) {
                return str_replace( "media='all'", "media='all' integrity='sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU' crossorigin='anonymous'", $html );
            }
        }

        return $html;
}
add_filter( 'style_loader_tag', 'add_attributes_to_all_styles', 10, 2 );

 

script_loader_tag I also would like to explain the script_loader_tag, because this is also handy, but this API works in combination with wp_enqueue_script.

The script_loader_tag API is almost the same, only some small differences, see documentation: https://developer.wordpress.org/reference/hooks/script_loader_tag/

apply_filters( 'script_loader_tag', $tag, $handle, $src ) Filters the HTML script tag of an enqueued script.

Below an example to defer a single script

function add_defer_jquery( $tag, $handle ) {
    if ( 'jquery' === $handle ) {
        return str_replace( "src", "defer src", $tag );
    }
    return $tag;
}
add_filter( 'script_loader_tag', 'add_defer_jquery', 10, 2 );

Below an example to defer more than one script

function add_defer_attribute( $tag, $handle ) {

    // add script handles to the array below
    $scripts_to_defer = array(
        'jquery',
        'jquery-migrate',
        'bootstrap-bundle-js'
    );

    foreach ( $scripts_to_defer as $defer_script ) {
        if ( $defer_script === $handle ) {
            return str_replace( "src", "defer src", $tag );
        }
    }

    return $tag;
}
add_filter( 'script_loader_tag', 'add_defer_attribute', 10, 2 );

So I have explained both API's style_loader_tag and script_loader_tag. And I gave some examples for both API's I hope that this is useful for a lot of people out there. I have experience with both API's.

 

UPDATE @CKMacLeod Thank you for your update, this clarifies things. We're mostly on the same page. As I said, I'm a WordPress developer and if you want to publish a theme and/or plugin on https://wordpress.org you're essentially forced to abide by the "WordPress Coding Standards" or they will simply reject your theme and/or plugin.

That's why I encourage developers out there to use "the WordPress way". I understand that sometimes there are no differences whatsoever, but it's also convenience. As you said yourself you could download Font Awesome and include it in your theme and/or plugin, this way you would only need to remove the style_loader_tag function and modify your wp_enqueue_style function.

And one last thing, in the past (5 years ago) some caching, combining and minifying plugins didn't work and most of the times I would find out why those developers who made the theme simply put things in the head in the theme and/or echoed them. Most caching plugins, who also (most of the time) provide options to combine, minify and delay execution of scripts became smarter and better at detecting bad code and working around them. But this is not preferred. That's why I encourage people to code with standards/conventions in mind.

As a developer, you always need to take into consideration what people could do with your code and taking compatibility in mind. So not taking the easy solution but the best optimal solution. I hope I have clarified my viewpoint.

EDIT @CKMacLeod Thank you for the (technical) debate, I hope that you realize how important this is (using WordPress API's in your own development). Again, I have been looking around and even now if I look at the FAQ's of most popular minify plugins I usually see this one way or the other, for example:

Question: Why are some of the CSS and JS files not being merged? Answer: The plugin only processes JS and CSS files enqueued using the official WordPress API method – https://developer.wordpress.org/themes/basics/including-css-javascript/ -as well as files from the same domain (unless specified on the settings).

See FAQ: https://wordpress.org/plugins/fast-velocity-minify/

 

    Remzi Cavdar

    Nov 23, 2018 at 10:34

  • RC - I do think your answer may be overall better WordPress practice than mine (though I'll want to do some more research on enqueueing externally hosted scripts and files). Still, I think we should be clear on our justifications, and not oversell them, and also acknowledge that the right answer for incorporating 3rd party services may vary in different contexts. On this note, the other answer that neither of us considered, by the way, is using a good plug-in - like Better Font Awesome for FA, since they may handle updating and other tasks well.

    CK MacLeod

    Nov 24, 2018 at 16:31

  • Yeah, you're right about using a plugin for FA. I only don't know if this is also preferred when devs create a WP theme. Usually you would want to include everything in your theme and use less plugins as possible out of the box.

    Remzi Cavdar

    Nov 24, 2018 at 21:26

  • Check these solutions, stackoverflow.com/questions/44827134/…

    Gnanasekaran Loganathan

    Oct 28, 2019 at 14:44

 

The review of script_ and style_loader_tag by @Remzi Cavdar is interesting, but, at the risk of provoking some outrage, and in the hope that someone can remind me what the advantage of using the WP queue would be in cases like this one, I'll recommend taking the easy way out, and loading Fontawesome's stylesheet via hook.

/* ADD FONTAWESOME 5.5.0 via action hook */
add_action( 'wp_head', 'sewpd_add_fontawesome' );

function sewpd_add_fontawesome() {

echo '
<!--FONTAWESOME 5.5.0 added via functions.php -->
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" integrity="sha384-B4dIYHKNBt8Bc12p+WXckhzcICo0wtJAoU8YZTY5qE0Id1GSseTk6S+L3BlXeVIU" crossorigin="anonymous">
<!--END FONTAWESOME -->
'; 

}

Some might even argue that, if you're using FA only for, say, some icons in the theme footer or within posts, you should add it lower, within the body of the page, since that way it won't come up as render-blocking, but I confess I've never done that... And I won't go as far as to recommend adding it directly to a header.php or other template file. That would be wrong. 😉

UPDATE

Remzi Cavdar was kind enough to reply to my request for a reminder as to why simply adding a Fontawesome or similar tag via wp_head() hook might be less desirable than utilizing the WordPress queue. He refers generally to the notion of best practices and somewhat more specifically to the idea that caching plugins might need to be able to access the stylesheet via the queue.

Before I go into detail, I'll say that, though I don't actually know of any significant particular justification other than that it's kind of "the WordPress Way," I like Comrade Cavdar's approach, and may use it myself in the future.

His other claims for it, however, are not persuasive to me. Maybe he or someone else can add to them. If so, I'm all ears. Bottom-line, as far as I can tell, after running over 20 tests on Pingdom and GTMetrix comparing "add via queue" vs "add via head" on a test blog, there is no significant and consistent difference in terms of graded performance, total number of page requests, or load times (e.g., "First Paint," "First Contentful Paint," and "OnLoad" at GTMetrix) between the two approaches.

Regarding caching specifically, caching plugins can't do very much with externally hosted files, whether or not they're added to the WP queue. The files themselves will remain unaffected, and your page will still generate a request for each one.

More generally, I've seen a wide range of different approaches for loading scripts and styles. Some of them will partly or entirely bypass the WP queue. It's certainly conceivable that there will be instances - a function that utilizes an array of style handles while preventing them from being loaded on particular pages, say - where having the Fontawesome or other 3rd Party Tag enqueued will be marginally useful, and that initial deploying two functions - enqueueing and filtering - will actually turn out to be more parsimonious than simply loading one.

In the case of FA, the stylesheet is already minified and is loaded via FA's own CDN. Its intrinsic impact on performance will be minimal, though, whether loaded via wp_head() or via the queue, it will still register demerits in multiple spots on performance graders - the same ones, like Google Page Speed Insights and the aforementioned GTMetrix and Pingdom, that will dock you a performance point for not saving a few bytes (not even kilobytes) re-optimizing one or another image file.

Loading via wp_head rather than the queue may trip a "correct order of scripts and styles" check (even though someone else will grade you higher for loading the externally hosted file after locally hosted ones), but, if you're really concerned about loading FA in the best possible way for your site, then you'd try locally hosting its files and sub-files, both its style and the fonts that its stylesheet calls via @font-face. In that case you could enqueue the stylesheet just like any other local file, concatenate and combine it via an optimizing plugin or directly "by hand." You could even make your own awesome modifications of Fontawesome and integrate them with your theme stylesheet and structure. Or (as earlier briefly mentioned) you could try out some more exotic performance optimization tactics like adding the CSS inline right before it was needed in the structure of a specific page.

Anyway, you wouldn't need to worry about the new "integrity" and "cross-origin" tags, and you also wouldn't have to worry if someday Fontawesome forgets to pay its CDN bill.

Or you may be working on a site that's already a complete mess under the hood, with stylesheets and scripts loaded in every which way, and it might be easier just to have your latest addition at the top of the functions.php file so you or the next developer can locate it again easily...

 

Share

Improve this answer

Follow

edited Nov 23, 2018 at 21:03

answered Nov 22, 2018 at 8:26

CK MacLeod's user avatar

CK MacLeod

1,8471212 silver badges1515 bronze badges

  • I'm curious as well, what's the downside of doing it this way, or directly adding it to a theme file?

    Josh

    Nov 22, 2018 at 15:52

  • Thank you for your viewpoint, the only thing is that your solution will frustrate a lot of minify and caching plugins. Like: wordpress.org/plugins/fast-velocity-minify, wordpress.org/plugins/wp-fastest-cache and etca....

    Remzi Cavdar

    Nov 22, 2018 at 19:02

  • 1

    The other plugins are able to manipulate the stylesheets and scripts if they are properly enqueued, if you put your code directly in the head these plugins will not be able to minify, combine and build a cache with propper order.

    Remzi Cavdar

    Nov 22, 2018 at 19:05

  • Remzi Cavdar: Thanks for you reply, but, before I edit my answer and address the issues you raise in detail, I wonder if you have any examples of them specifically in relation to Fontawesome or generally in relation to other stylesheets like it, as in already minified and externally hosted.

    CK MacLeod

    Nov 23, 2018 at 8:01

  • @CKMacLeod Let's say you want to use a plugin who combines and minifies your stylesheet files. Most plugin like these need an API to check the stylesheets, they check which one are enqueued. Some have fallbacks to check in it's echod, but this is bad practice, see: make.wordpress.org/core/handbook/best-practices/…

    Remzi Cavdar

    Nov 23, 2018 at 10:39

  • Thanks, but that's not a specific example in any sense. It's just a link to the best practices page.

    CK MacLeod

    Nov 23, 2018 at 18:40

  • @CKMacLeod Thank you for your update, this clarifies things. We're mostly on the same page. I have also written an explanation why I encourage people to use WordPress Coding Standards, basically, if you want to publish a theme and/or plugin you're essentially forced to abide by the "WordPress Coding Standards" or they will simply reject your theme and/or plugin.

    Remzi Cavdar

    Nov 24, 2018 at 6:54

  • 1

    The "wordpress way" ensures maximal compatibility with plugins. Whether it is for fetching things from CDN, or removing the link for some specific pages, in your way it is just not going to be possible without actually editing the code. +1 for standing for your believes but as an answer here it is a -1

    Mark Kaplun

    Nov 27, 2018 at 17:16

  • 1

    I question your tests. I'm sure that you set up a perfectly reasonable testing environment to test a particular thing: either green-fields WP (clean with nothing else) or some configuration that you already had. My experience with real-world WP setups is that they are usually either very sparse or very complicated. By using the wp_head hook, you're doing what many WP developers do, which is take advantage of an unregulated environment (there is very little policing on WP). Your test may show completely different results in many real environments.

    Stephan Samuel

    May 29, 2020 at 17:39

  • @StephanSamuel Luckily when people want to publish their theme(s) and/or plugin(s) on wp.org they need to abide by the WP Standards otherwise they get rejected. I don't know about the quality testing on third party websites like themeforest.net. Therefore end users can trust the wp.org themes and plugins.

    Remzi Cavdar

    Sep 4, 2020 at 20:55

Scroll to Top