What is the idea way to register/enqueue scripts and/or styles for use in plugins?
我最近做了一个插件
simple plugin 添加带有短代码的用户头像/坟墓者。我有不同的风格选项来显示化身(方形、圆形等),并决定将css直接放在短代码本身中。
然而,我现在意识到这不是一个好方法,因为每次在页面上使用短代码时,它都会重复css。我在这个网站上见过其他几种方法,wp codex甚至有两个自己的例子,所以很难知道哪种方法最一致、最快。
以下是我目前了解的方法:
Method 1: Include directly in shortcode - <这就是我目前在插件中所做的,但似乎并不好,因为它重复代码
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\' ) );
Method 2: Use class for enqueueing scripts or styles conditionally
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();
Method 3: Using get_shortcode_regex();
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\' );
Method 4: Using has_shortcode();
function custom_shortcode_scripts() {
global $post;
if( is_a( $post, \'WP_Post\' ) && has_shortcode( $post->post_content, \'myshortcode\') ) {
wp_enqueue_script( \'my-script\');
}
}
add_action( \'wp_enqueue_scripts\', \'custom_shortcode_scripts\');
最合适的回答,由SO网友:jblanche 整理而成
我找到了另一种适合我的方法:
初始化插件时,不要将脚本和样式排队,而是将它们注册到wp_register_style
和wp_register_script
.
接下来,您可以根据需要加载脚本/样式。例如,当使用wp_enqueue_style("your_style")
和wp_enqueue_script("your_script")
.
Here is an example plugin using this method that lets you use get_avatar in a shortcode. The stylesheet is only enqueued when the shortcode is present.
用法(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\' );
}
SO网友:gmazzap
在开始回答之前,我必须说,关于这个主题,css和js是不一样的。
原因很简单:虽然将js添加到页面主体(页脚)是一种常见且有效的方式,但css需要放置在<head>
页面部分:即使大多数浏览器可以在页面主体中正确呈现css,这也是无效的HTML代码。
渲染短代码时,<head>
节已打印,这意味着可以添加js,但页脚上没有任何问题,但必须添加cssbefore 将呈现短代码。
脚本
如果您的短代码只需要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中所做的。事实上,这两种方法都做相同的事情,但是has_shortcode
WP 3.6中添加了get_shortcode_regex
自版本2.5起可用,因此请使用get_shortcode_regex
仅当您希望使插件与旧版本兼容时。
始终在所有页面中添加短代码样式
问题#1的问题是性能。Regex是非常慢的操作,在所有帖子的循环中启动Regex可能会持续减慢页面速度。此外,在主题中,只显示存档中的帖子摘录,并仅在单数视图中使用短代码显示完整内容是一项非常常见的任务。如果出现这种情况,当显示归档文件时,插件将在循环中启动一个regex匹配,目的是添加一种永远不会使用的样式:不必要的双重性能影响:减缓页面生成速度+额外的不必要的HTTP请求
#2的问题还是性能。向所有页面添加样式意味着为所有页面添加额外的HTTP请求,即使不需要。即使服务器端页面生成时间不受影响,总页面呈现时间也会受到影响,并且对于所有站点页面。
那么,插件开发人员应该做什么呢
我认为最好的办法是在插件中添加一个选项页面,用户可以选择是只在单一视图中处理短代码,还是在归档中处理短代码。在这两种情况下,最好提供另一个选项来选择哪些帖子类型启用了短代码。
这样就可以钩住"template_redirect"
检查当前查询是否满足要求,并在这种情况下添加样式。
若用户选择只在单一的帖子视图中使用短代码,那个么检查帖子是否有短代码是一个好主意:一旦只需要一个正则表达式,它就不应该让页面速度降低这么多。
如果用户选择在归档文件中使用shortcode,那么如果帖子数量很大,我将避免对所有帖子运行regex,如果查询符合要求,则只需将样式排队即可。
在这方面考虑“高”的应该是使用一些性能测试,或者作为替代方案,添加另一个选项并让用户选择。