注册/排队脚本和/或样式以便在插件中使用的想法是什么?

我最近制作了一个插件简单插件,以使用简码添加用户头像/ gravatar。我有不同的样式选项来显示化身(正方形,圆形等),并决定将CSS直接放入简码本身。

但是,我现在意识到这不是一个好方法,因为每次在页面上使用简码时,它都会重复CSS。我在该站点上还看到了其他几种方法,并且wp Codex甚至有自己的两个示例,因此很难知道哪种方法最一致,最快。

以下是我目前知道的方法:

方法1:直接包含在简码中-
这是我目前在插件中所做的事情但由于重复代码而显得不太好。

class My_Shortcode {
function handle_shortcode( $atts, $content="" ) {
/* simply enqueue or print the scripts/styles in the shortcode itself */
?>
<style type="text/css">

</style>
<?php
    return "$content";
     }
}
add_shortcode( 'myshortcode', array( 'My_Shortcode', 'handle_shortcode' ) );


方法2:使用类有条件地使脚本或样式入队/>
方法3:使用get_shortcode_regex();

class My_Shortcode {
    static $add_script;
    static function init() {
        add_shortcode('myshortcode', array(__CLASS__, 'handle_shortcode'));
        add_action('init', array(__CLASS__, 'register_script'));
        add_action('wp_footer', array(__CLASS__, 'print_script'));
    }
    static function handle_shortcode($atts) {
        self::$add_script = true;
        // shortcode handling here
    }
    static function register_script() {
        wp_register_script('my-script', plugins_url('my-script.js', __FILE__), array('jquery'), '1.0', true);
    }
    static function print_script() {
        if ( ! self::$add_script )
            return;
        wp_print_scripts('my-script');
    }
}
My_Shortcode::init();


方法4:使用has_shortcode();

function your_prefix_detect_shortcode() {

    global $wp_query;   
    $posts = $wp_query->posts;
    $pattern = get_shortcode_regex();

    foreach ($posts as $post){
        if (   preg_match_all( '/'. $pattern .'/s', $post->post_content, $matches )
            && array_key_exists( 2, $matches )
            && in_array( 'myshortcode', $matches[2] ) )
        {
            // css/js 
            break;  
        }    
    }
}
add_action( 'wp', 'your_prefix_detect_shortcode' );


评论

我认为方法4:使用has_shortcode();最好是因为它将确保如果帖子内容包含简码,则脚本和样式将加载一次,而不管简码的多次使用如何。尽管它可能不适用于小部件或边栏中的短代码,但是不确定。如果是用于插件,那么我不建议您将脚本与短代码绑定,因为有些脚本可能会调用您的函数而不是短代码来获得所需的输出。

如何仅将样式表添加到具有特定短代码的页面的可能重复项?

方法4很好,但是如果没有将短码直接添加到WP内容区域中,而是将某些其他第三方插件选项直接添加到WP内容区域中,则可能会产生一个问题。在简码功能中添加支票可能会有帮助! wp_style_is与方法4一起使用,并将样式排队到那里,以防以前的wp_enqueue_scripts回调中未添加样式

#1 楼

我发现了另一种对我有用的方法:


初始化插件时,请勿使您的脚本和样式入队,而应在wp_register_stylewp_register_script中进行注册。


接下来,您可以按需加载脚本/样式。例如,当您使用wp_enqueue_style("your_style")wp_enqueue_script("your_script")渲染简码时。


这里是使用此方法的示例插件,可让您在简码中使用get_avatar。仅当存在简码时,样式表才会入队。
用法(ID默认为当前用户):
[get_avatar id="" size="32" default="mystery" alt="Profile Photo" class="round"]
function wpse_165754_avatar_shortcode_wp_enqueue_scripts() {
    wp_register_style( 'get-avatar-style', plugins_url( '/css/style.css', __FILE__ ), array(), '1.0.0', 'all' );
}

add_action( 'wp_enqueue_scripts', 'wpse_165754_avatar_shortcode_wp_enqueue_scripts' );
if ( function_exists( 'get_avatar' ) ) {
    function wpse_165754_user_avatar_shortcode( $attributes ) {

        global $current_user;
        get_currentuserinfo();

        extract( shortcode_atts(
                     array(
                         "id"      => $current_user->ID,
                         "size"    => 32,
                         "default" => 'mystery',
                         "alt"     => '',
                         "class"   => '',
                     ), $attributes, 'get_avatar' ) );
        
        $get_avatar = get_avatar( $id, $size, $default, $alt );

        wp_enqueue_style( 'get-avatar-style' );

        return '<span class="get_avatar ' . $class . '">' . $get_avatar . '</span>';
    }

    add_shortcode( 'get_avatar', wpse_165754_user_avatar_shortcode' );
}


评论


忘记了我去年问过这个问题,但是实际上我在很多情况下也已经开始这样做。有点像结合方法1和2。

–布莱恩·威利斯(Bryan Willis)
15年7月8日在17:36

此方法将CSS加载到页脚中,这肯定有局限性吗?

–雅各布·拉库亚(Jacob Raccuia)
17年4月21日在13:26

这绝对是正确的方法。当wp_enqueue_scripts钩子已经发生时,您需要有条件地加载脚本或样式表时,都可以使用此方法。 (在the_content钩子中的the_content期间解析了短代码,这意味着解析它时进入队列太晚了,除非您已经注册了脚本)

–杰拉德(JRad the Bad)
19-4-20在21:56



这没有帮助,因为当在shortcode函数中加载样式时会创建FOUT。最好使用has_shortcode方法。

–阿黛尔·拉扎(Adeel Raza)
10月14日10:27

#2 楼

在开始回答之前,我不得不说,关于此主题,css和js是不同的。

原因很简单:尽管将js添加到页面正文中(在页脚中)是一种常见且有效的方法,但css需要放置在页面的<head>部分中:即使大多数浏览器都可以在页面正文中正确呈现css,这不是有效的HTML代码。

呈现简码时,已经打印了<head>部分,这意味着可以添加js而不出现页脚问题,但是在呈现简码之前必须添加css。

脚本

如果简码只需要js,那么您很幸运,可以在简码回调主体中使用wp_enqueue_script

add_shortcode( 'myshortcode', 'my_handle_shortcode' );

function my_handle_shortcode() {
  wp_enqueue_script( 'myshortcodejs', '/path/to/js/file.js' );
  // rest of code here...
}


这样,即使短代码在页面中多次使用,您的脚本也仅添加到页脚一次。

样式

如果您的代码需要样式,则需要在实际呈现短代码之前采取行动。

有多种方法可以做到这一点:


查看当前查询中的所有帖子并添加简短内容代码样式(如果需要)。这是在OP中的方法3和方法4中执行的操作。实际上,这两种方法都具有相同的作用,但是WP 3.6中添加了has_shortcode,而自版本2.5起就提供了get_shortcode_regex,因此仅当希望使您的插件与旧版本兼容时才使用get_shortcode_regex。在所有页面中

问题

问题1是性能。正则表达式是相当慢的操作,在所有帖子循环中启动正则表达式可能会持续降低页面速度。此外,在主题中非常常见的任务是仅在档案中显示摘录后的内容,而仅在单一视图中显示带有短代码的完整内容。如果发生这种情况,则在显示存档时,您的插件将在循环中启动正则表达式匹配,以添加永不使用的样式:不必要的双重性能影响:减慢页面生成速度+其他不必要的HTTP请求

#2的问题还是性能。向所有页面添加样式意味着即使不需要时也为所有页面添加一个额外的HTTP请求。即使不影响服务器端页面的生成时间,总页面渲染时间以及所有站点页面也将受到影响。

那么,插件开发人员应该怎么做?

我认为最好的办法是在插件中添加一个选项页,用户可以在其中选择是否只在单一视图中甚至在存档中处理短代码。
在两种情况下,最好提供另一个选项来选择帖子类型启用简码。

可以通过钩住"template_redirect"来检查当前查询是否满足要求,并在这种情况下添加样式。

如果用户选择使用简码仅在单个帖子视图中检查一个帖子是否包含短代码是一个好主意:一旦只需要一个正则表达式,它就不会使页面变慢。

如果用户选择即使在存档中也使用短代码,那么如果帖子数量很多,我将避免对所有帖子运行regex,并且如果查询适合要求,则只排入样式。

在这方面考虑“高”的内容应该是使用一些性能测试获得的,或者作为替代,添加另一个选项并为用户提供选择。

评论


在这里值得注意的是,文档主体中的