主题和插件中使用的组件:如何获取文件URL?

时间:2017-06-29 作者:Blackbam

在我的项目中,我有一些组件,我在许多自定义插件以及一些自定义编码主题中使用这些组件,例如管理图像或视频选择器。

我在自定义git存储库中保存的内容。然而,由于这些组件在主题和插件中都有使用,我总是必须在从GIT中提取后手动更改URL获取程序。如果组件多次存在,这不是问题,我已经用function_exists.

这就是我在主题中使用的内容:

wp_enqueue_script(get_template_directory_uri().\'/libs/my_lib/admin_image_upload\', ...);
这是我在插件中使用的内容:

wp_enqueue_script(plugins_url(__FILE__).\'admin_image_upload.js\', ...);
有没有办法确定我当前的PHP文件是在插件文件夹中还是在主题文件夹中,以便我自动确定正确的路径?

2 个回复
SO网友:Rarst

有没有办法确定我当前的PHP文件是在插件文件夹中还是在主题文件夹中

一般来说,您总是有当前文件的路径(__FILE__) 因此,您可以随时检查您所在的位置,并与上下文进行比较。这在自定义站点中可能已经足够好了,但对于公共代码来说可能太脆弱了。有很多带有路径的边缘情况,因为它们可以高度定制。

您所面临的不仅仅是资产问题,还有依赖性问题—如何以不同的方式、无冲突地重用多个组件。

就我个人而言,我强烈考虑研究Composer,因为它是现代PHP中管理依赖关系的事实上的方法。这是。。。对于公开发布的WP扩展的怪癖来说,这并不完美,但您的案例听起来更像是以自定义工作为中心的。

SO网友:Dave Romsey

这里有一个解决方案,它将返回相对于文件位置的URL,以及指示文件所在位置的字符串,即mu插件/插件/主题。

此代码改编自get_url_from_dir() 在meta box库中使用CMB2.

/**
 * Converts a system file path to a URL.
 * Returns URL and the detected location of the file.
 *
 * Based on get_url_from_dir() via CMB2
 * @link https://github.com/CMB2/CMB2
 * 
 * @param  string $file file path to convert.
 * @return string Converted URL.
 * @return array|bool (on error)
 *  array
 *    $url string Converted URL.
 *    $location string location of dir (mu-plugins, plugins, theme)
 *
 */
function wpse_get_url_info_from_file( $file ) {
    $file = wp_normalize_path( $file );
    $test_dir = pathinfo( $file );

    if ( ! $test_dir ) {
        return false;
    }

    $test_dir = trailingslashit( $test_dir[\'dirname\'] );

    // Test if we are in the mu-plugins dir.
    if ( 0 === strpos( $test_dir, wp_normalize_path( WPMU_PLUGIN_DIR ) ) ) {
        return [
            \'url\' => trailingslashit( plugins_url( \'\', $file ) ),
            \'location\' => \'mu-plugins\'
        ];
    }

    // Test if we are in the plugins dir.
    if ( 0 === strpos( $test_dir, wp_normalize_path( WP_PLUGIN_DIR ) ) ) {
        return [
            \'url\' => trailingslashit( plugins_url( \'\', $file ) ),
            \'location\' => \'plugins\'
        ];
    }

    // Now let\'s test if we are in the theme dir.
    $theme_root = wp_normalize_path( get_theme_root() );
    if ( 0 === strpos( $file, $theme_root ) ) {
        // Ok, then use get_theme_root_uri.
        $url = set_url_scheme(
            trailingslashit(
                str_replace(
                    untrailingslashit( $theme_root ),
                    untrailingslashit( get_theme_root_uri() ),
                    $test_dir
                )
            )
        );

        return [
            \'url\' => $url,
            \'location\' => \'theme\'
        ];
    }
}
例如,如果我们有一个名为wpse 居住在plugins-directory/wpse 还有一个主题my-theme, 我们可以在插件或主题中使用以下代码将admin_image_upload.js 文件,它位于插件和主题的不同目录中。

add_action( \'wp_enqueue_scripts\', \'wpse_enqueue_js_based_on_location\' );
function wpse_enqueue_js_based_on_location() {
    $url_info = wpse_get_url_info_from_file( __FILE__ );
    //exit ( print_r( $url_info ) );

    // Bail if something is wrong.
    if ( ! $url_info ) {
        return;
    }

    // Bail if something is wrong.
    if ( ! isset( $url_info[\'url\'] ) || ! isset( $url_info[\'location\'] ) ) {
        return;
    }

    // Enqueue the JS based on detected location of the file.
    if ( \'plugins\' === $url_info[\'location\'] ) {
        wp_enqueue_script( \'wpse-js\',  plugins_url( \'/admin_image_upload.js\', __FILE__ ) );
    } elseif ( \'theme\' === $url_info[\'location\'] ) {
        wp_enqueue_script( \'wpse-js\', get_template_directory_uri() . \'/libs/my_lib/admin_image_upload.js\' );
    }
}
从的根目录中的文件使用上述代码时wpse 插件,$url_info 将如下所示:

Array(
    [url] => http://example.com/wp-content/plugins/wpse/
    [location] => plugins
)
如果我们在一个主题的functions.php, $url_info 将如下所示:

Array(
    [url] => http://example.com/wp-content/themes/my-theme/
    [location] => theme
)

结束

相关推荐

WordPress Custom URLs

根据maioman发布的链接,我对以下问题进行了修改:我很难使用自定义的帖子类型/分类法。我想要一个自定义的帖子类型的剧集,并且自定义帖子类型的分类是包含用户生成的术语的剧集。我能够剧集/自定义术语名称/工作。如果你转到这里,它会显示与此术语相关的所有帖子。然而,如果你在剧集/自定义术语名称/帖子标题上看到一篇帖子,我会看到404页。function episodes() { $labels = array( \'name\' => _