当我开发插件时,通过在不同的wp-content目录中链接我的插件目录,可以在多个版本的WordPress上测试它们。这很棒,因为我只需要编辑一次文件,但是它破坏了在插件中生成对资源的引用的重要结构:__FILE__指向物理插件位置,而不是wp-content中的位置。我应该如何解决?

我的目录结构如下:



/path/to/wordpress/development/dir/


plugin-development/


monkeyman-rewrite-analyzer/

monkeyman-rewrite-analyzer.php

js/

monkeyman-rewrite-analyzer.js







versions/


3.1/


wp-content/


plugins/


monkeyman-rewrite-analyzer作为上述插件的符号链接







3.1-multi-dir/


wp-content/



plugins/


monkeyman-rewrite-analyzer作为上述插件的符号链接








3.1-multi-domain/


wp-content/


plugins/


monkeyman-rewrite-analyzer作为上述插件的符号链接











如果要排队Javascript文件,应该请使用plugins_url( 'monkeyman-rewrite-analyzer.js', [base file] ),但此处无法使用__FILE__,因为该行为ual文件路径将是/path/to/wordpress/development/dir/plugin-development/monkeyman-rewrite-analyzer/monkeyman-rewrite-analyzer.php,而不是/path/to/wordpress/development/dir/versions/*/wp-content/plugins/monkeyman-rewrite-analyzer/monkeyman-rewrite-analyzer.php,因此WordPress无法删除第一部分并生成相对于WordPress安装的URL。

#1 楼

问题可以通过将必需的插件挂接到plugins_url过滤器中来部分解决。

不能解决所有其他使用plugin_basename()的情况,例如register_activation_hook()和co。

更多信息:http://core.trac.wordpress.org/ticket/16953

评论


我认为不建议您使用WP_PLUGIN_URL,因为应该允许管理员更改此特定插件目录的名称,但是还有其他避免该更改的理由吗?确实,您的机票将是一个简单的解决方案。

– Jan Fabry
11-4-20在11:38



反之。 WP_PLUGIN_URL仅包含直接指向“插件”目录的URL。查看最新答案。

–抄写员
2011-4-20 15:18



@scribu:但是,如果我的插件位于/ external / folder / banana-plugin /中,但管理员以/ httpd-root / wp-content / plugins / apple-plugin /的身份链接到该目录,该怎么办?然后它将尝试转到/ wp-content / plugins / banana-plugin /,不是吗?而且我相信管理员应该可以自由选择单个插件目录名称?

– Jan Fabry
2011年4月20日15:35

我不再与您争论,因为我找到了解决方案:“ plugins_url”过滤器。再次更新答案。

–抄写员
2011年4月20日在15:38

FWIW此解决方案可能容易出错,并且仅在所有插件加载后才使用plugins_url()依赖于插件开发人员,否则您将无法在调用函数之前注册过滤器。 Akismet插件和许多其他插件都存在该问题。

–jerclarke
2011-6-10 14:09

#2 楼

我目前使用一种技巧来获取WordPress相对文件的位置:wp_get_active_and_valid_plugins()返回文件路径,而wp_settings.php循环遍历它们并包含文件。因此,全局$plugin变量将引用您当前的插件(当然,仅在加载插件时,因此我将其保存在带前缀的全局变量中):

$monkeyman_Rewrite_Analyzer_file = $plugin;


因为插件也可以作为必需插件或网络插件加载,并且这些循环使用其他变量名,完整的代码如下所示:

$monkeyman_Rewrite_Analyzer_file = __FILE__;
if ( isset( $mu_plugin ) ) {
    $monkeyman_Rewrite_Analyzer_file = $mu_plugin;
}
if ( isset( $network_plugin ) ) {
    $monkeyman_Rewrite_Analyzer_file = $network_plugin;
}
if ( isset( $plugin ) ) {
    $monkeyman_Rewrite_Analyzer_file = $plugin;
}


后备仍然是__FILE__,因此,如果将来有人更改循环变量名称,我的代码仍应可用于所有安装的99%,只有我的开发设置会失败,并且我可以轻松发布新版本。

评论


很好的解决方案,@ Jan。我通过调用函数和循环实现了类似的事情,因为我忘记了这些变量可以全局访问。感谢您在这里的帖子,我意识到我可以使它变得更加简单。顺便说一句,在运行if语句之前,我还要测试false === strpos(__FILE__,WP_CONTENT_DIR),因为我假设插件是否在WP_CONTENT_DIR中没有符号链接;我希望这是正确的逻辑。

– MikeSchinkel
2012年11月18日7:45



#3 楼

错误46260中的注释建议使用$_SERVER["SCRIPT_FILENAME"]而不是__FILE__。这行得通吗?

评论


不,在包含的文件中不会更改。因此,如果index.php包含library.php,library.php中的$ _SERVER ['SCRIPT_FILENAME']仍为index.php。但是,感谢您对该错误的引用,我将密切关注它!

– Jan Fabry
2011年4月20日在10:25



#4 楼

如果正确使用,$_SERVER["SCRIPT_FILENAME"]可以正常工作。您只需要使用它来设置基本路径,然后使用相对于该基本路径的路径包含文件。

类似的东西:

$plugin_dir = dirname($_SERVER["SCRIPT_FILENAME"]);
$myFile = $plugin_dir."/includes/js/myJavascriptFile.js";


请注意,如果您还没有访问wp-blog-header.php的权限(例如,在处理基于ajax的表单请求中),此功能将更为有用。