web-dev-qa-db-ja.com

テーマとプラグインで使用されるコンポーネント:ファイルのURLを取得する方法

私のプロジェクトでは私が私のようないくつかのカスタムコード化されたテーマと同様に私が多くのカスタムプラグインで使用するいくつかのコンポーネントを持っています。管理者画像またはビデオセレクタ。

私がカスタム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ファイルがプラグインのフォルダ内にあるのか、テーマのフォルダ内にあるのかを判断する方法はありますか?

1
Blackbam

現在のPHPファイルがプラグインのフォルダ内にあるのか、テーマのフォルダ内にあるのかを判断する方法はありますか

おおまかにあなたは常に現在のファイルへのパス(__FILE__)を持っているので、あなたはそれをあなたがどこにいるのかを常に調べてコンテキストと比較することができます。これはカスタムサイトでは十分に有効かもしれませんが、パブリックコードに対しては脆弱すぎる可能性があります。それらは高度にカスタマイズされることができるのでパスでたくさんのEdgeケースがあります。

あなたが持っているのは資産問題だけではなく、依存関係問題でも - どうやって複数のコンポーネントをさまざまな方法で、競合することなく再利用できますか。

最近のPHPで依存関係を管理するための事実上の方法であるため、個人的にはComposerを検討することを強くお勧めします。それは…公に配布されたWP拡張機能の奇妙な話には完璧ではありませんが、あなたのケースはとにかくカスタムワークに焦点を当てたように思えます。

2
Rarst

これは、ファイルのURLをその場所を基準にしてファイルに返すソリューションと、ファイルが存在する場所を示す文字列、つまりmu-plugins/plugins/themeです。

このコードは、メタボックスライブラリ CMB2 で使用されているget_url_from_dir()から修正されています。

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

たとえば、plugins-directory/wpse内に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
)
1
Dave Romsey