如何在wp_register_style中添加交叉来源和完整性?(字体真棒5)


13

我正在将Font Awesome 4升级到版本5,该版本将完整性和跨域属性引入了<link rel="stylesheet">标记。

目前,我正在使用:

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

输出为:

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

有了Font Awesome 5,它引入了两个新的属性和值(integritycrossorigin),例如:

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

所以,我需要找到我怎么能既完整性和crossorigin添加到wp_register_style,我都试过,但我会尝试使用wp_style_add_data都失败了,它似乎是这种方法仅支持conditionalrtl并且suffixalttitle



感谢@JacobPeattie,问题有点不同,但是给出的答案可能适用于这种情况。然而,它可以追溯到2016年,也许现在有了一种似乎不太hacky的方式……
Pipo

@Pipo我是WordPress开发人员,做了几个WordPress插件,我经常使用style_loader_tag和script_loader_tag进行一些自定义加载。甚至在我的脚本标签中添加了defer和async。看到我的一个开源插件:github.com/Remzi1993/wp-jquery-manager
Remzi Cavdar

@Pipo你也是对的。另一则帖子已经过时了,将不再起作用。在第一个示例中,我展示了如何通过简单的字符串替换来实现此目的。我还提供了一些其他信息,以便其他人可以使用此信息
Remzi Cavdar

@JacobPeattie你可以看看吗?我可能有一些语法错误,英语是我的第二语言
Remzi Cavdar

Answers:


16

style_loader_tag
style_loader_tag是官方的WordPress API,请参见文档:https : //developer.wordpress.org/reference/hooks/style_loader_tag/

apply_filters( 'style_loader_tag', $html, $handle, $href, $media )
筛选已排队样式的HTML链接标记。


首先将样式表放入队列,请参阅文档: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 );

$handle'font-awesome-5'
我做的null,这样就没有版本号。这样它将被缓存。

简单的str_replace
简单的str_replace足以实现您想要的功能,请参见下面的示例

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 );


添加不同的属性
下面的示例为(多个)不同的样式表添加不同的属性。

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 );


为所有样式添加属性
下面的示例为多个样式表添加相同的属性

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
我也想解释一下script_loader_tag,因为它也很方便,但是此API与wp_enqueue_script结合使用。

script_loader_tag API几乎相同,只有一些小差异,请参阅文档:https : //developer.wordpress.org/reference/hooks/script_loader_tag/

apply_filters( 'script_loader_tag', $tag, $handle, $src )
筛选已排队脚本的HTML脚本标签。


下面是延迟单个脚本的示例

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 );


下面的示例推迟了多个脚本

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 );

因此,我已经解释了API style_loader_tagscript_loader_tag。我为这两个API给出了一些示例,希望对很多人有用。我对这两个API都有经验。


UPDATE
@CKMacLeod感谢您的更新,这使事情变得清晰起来。我们大多在同一页面上。就像我说的,我是WordPress开发人员,如果您想在https://wordpress.org上发布主题和/或插件,您实际上会被迫遵守“ WordPress编码标准 ”,否则他们将拒绝您的主题和/或插件。

这就是为什么我鼓励开发人员使用“ WordPress方式”的原因。我知道有时候之间没有任何区别,但这也很方便。正如您自己说的那样,您可以下载Font Awesome并将其包含在主题和/或插件中,这样,您只需删除style_loader_tag函数并修改wp_enqueue_style函数。

最后一件事,在过去(5年前)中,某些缓存,组合和缩小插件不起作用,而且大多数时候,我会发现为什么制作主题的开发人员只是将主题放在首位, /或回应他们。大多数(大部分时间)还提供组合,最小化和延迟脚本执行的选项的缓存插件变得更聪明,并且在检测错误代码和解决它们方面变得更好。但这不是首选。这就是为什么我鼓励人们在编写代码时要牢记标准/惯例。

作为开发人员,您始终需要考虑人们可以使用您的代码做什么,并且要考虑兼容性。因此,不是采用简单的解决方案而是最佳的最佳解决方案。我希望我已经阐明了我的观点。

EDIT
@CKMacLeod感谢您的(技术性)辩论,我希望您意识到它的重要性(在您自己的开发中使用WordPress API)。同样,我一直在环顾四周,即使现在查看最受欢迎的minify插件的FAQ,我通常也会以一种或另一种方式看到这种情况,例如:

问题:为什么某些CSS和JS文件没有合并?
答:该插件仅处理使用官方WordPress API方法排队的JS和CSS文件-https: //developer.wordpress.org/themes/basics/includes-css-javascript/- 以及来自同一域的文件(除非指定在设置上)。

请参阅常见问题解答:https//wordpress.org/plugins/fast-velocity-minify/


@Pipo不客气:)
Remzi Cavdar

RC-我确实认为您的答案可能总体上比我的WordPress更好(尽管我想做更多有关使外部托管脚本和文件入列的研究)。尽管如此,我认为我们应该清楚说明自己的理由,而不是过度推销它们,并且也承认,合并第三方服务的正确答案可能会因情况而异。关于这一点,顺便提一句,我们俩都没有考虑的另一个答案是使用一个好的插件,例如FA的Better Font Awesome,因为他们可能很好地处理了更新和其他任务。
CK MacLeod

是的,使用FA插件是正确的。我只是不知道在开发人员创建WP主题时是否也首选此方法。通常,您会希望将所有内容都包含在主题中,并尽可能减少使用开箱即用的插件。
Remzi Cavdar

检查这些解决方案,stackoverflow.com
questions/44827134/…

-1

@Remzi Cavdar对script_和style_loader_tag的评论很有趣,但是冒着激怒的风险,希望有人提醒我在这种情况下使用WP队列的好处是什么,我我们建议您采取简单的方法,并通过钩子加载Fontawesome的样式表。

/* 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 -->
'; 

}

甚至有人可能会争辩说,如果仅将FA用于主题页脚或帖子中的某些图标,则应在页面正文下方将其添加,因为那样就不会出现。渲染块,但我承认我从未做过...而且我也不会推荐直接将其添加到header.php或其他模板文件。那是错误的。;)

更新

Remzi Cavdar很高兴回答我的要求,以提醒我为什么通过wp_head()钩子简单添加Fontawesome或类似标签可能比使用WordPress队列更不受欢迎。他通常指的是最佳实践的概念,而更具体地讲是指缓存插件可能需要能够通过队列访问样式表的想法。

在我详细介绍之前,我要说的是,尽管除了“ WordPress方式”之外,我实际上不知道任何重要的特殊理由,但我喜欢卡夫达尔同志的方法,将来可能会自己使用它。 。

但是,他对它的其他主张对我来说没有说服力。也许他或其他人可以添加到他们。如果是这样,我全神贯注。据我所知,最基本的是,在Pingdom和GTMetrix上运行了20多个测试,将测试博客上的“通过队列添加”与“通过头部添加”进行了比较之后,在分级性能方面没有显着且一致的差异,两种方法之间的页面请求总数或加载时间(例如,GTMetrix的“ First Paint”,“ First Contentful Paint”和“ OnLoad”)。

关于缓存,无论缓存插件是否被添加到WP队列中,缓存插件都不能很好地处理它们。文件本身将不受影响,并且您的页面仍将为每个文件生成一个请求。

一般来说,我已经看到了各种各样的加载脚本和样式的方法。其中一些将部分或全部绕过WP队列。当然可以想象会有实例-一个利用一系列样式句柄同时防止将它们加载到特定页面上的函数,例如-将Fontawesome或其他3rd Party Tag排入队列将非常有用,并且最初部署两个实际上,入队和过滤功能要比简单地加载一个功能更简单。

对于FA,样式表已经缩小,并通过FA自己的CDN加载。但是,无论是通过wp_head()还是通过队列加载,它对性能的内在影响都将是最小的,它仍然会在性能分级器上的多个位置记录缺点,例如,相同的位置,例如Google Page Speed Insights和上述的GTMetrix和Pingdom,这样可以为您节省一个性能点,因为它无需保存几个字节(甚至不到千字节)就可以重新优化一个或另一个图像文件。

通过wp_head而不是队列进行加载可能会触发“正确的脚本和样式顺序”检查(即使其他人会在本地托管文件之后对您加载外部托管文件给予更高的评价),但是,如果您真的担心加载以您网站的最佳方式访问FA,然后尝试在本地托管其文件和子文件,其样式和样式表通过@ font-face调用的字体。在这种情况下,您可以像其他任何本地文件一样排入样式表,通过优化插件或直接“手动”将其串联并合并。您甚至可以对Fontawesome进行出色的修改,并将其与主题样式表和结构集成。或者(如前所述),您可以尝试一些更奇特的性能优化策略,例如在特定页面的结构中直接添加CSS内联。

无论如何,您无需担心新的“完整性”和“跨域”标签,并且即使有一天Fontawesome忘记支付其CDN账单,也不必担心。

或者,您可能正在一个已经完全混乱的网站上工作,以各种方式加载样式表和脚本,而将最新添加的内容放在functions.php文件顶部可能会更容易,因此您或下一位开发人员可以轻松地再次找到它...


我也很好奇,这样做或直接将其添加到主题文件的缺点是什么?
耶什

感谢您的观点,唯一的问题是您的解决方案将使许多缩小和缓存插件受挫。像:wordpress.org/plugins/fast-velocity-minifywordpress.org/plugins/wp-fastest-cache和ETCA ....
Remzi Cavdar

1
如果正确地将其他插件排入队列,其他插件将能够处理样式表和脚本,如果将代码直接放在头部,这些插件将无法以适当的顺序最小化,组合和构建缓存。
Remzi Cavdar

Remzi Cavdar:谢谢您的答复,但是,在我编辑我的答案并详细解决您提出的问题之前,我想知道您是否有一些示例与Fontawesome有关,或者与其他样式表有关,例如已经缩小并由外部托管。
CK MacLeod

1
“ WordPress方式”确保与插件的最大兼容性。无论是从CDN中获取内容,还是删除某些特定页面的链接,如果不实际编辑代码,就无法实现。+1可代表您的信仰,但在这里,作为答案,它是-1
Mark Kaplun
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.