web-dev-qa-db-ja.com

スクリプト/スタイルを条件付きでロードできるように、関数が任意のページで起動されたかどうかを検出する方法

小さなギャラリープラグインを作成しています。ギャラリーがテンプレートタグを介してロードされている場合は、スクリプト/スタイルをページにのみロードします。テーマ内の必要な場所から投稿のギャラリーを呼び出すためにテンプレートタグを使用すると、投稿IDパラメータを取得できます。

私はこれをどのようにするかを私は知っています(meta_keyを検索して現在表示されている記事と突き合わせることができます)が、ホームページ(または他のページ)にギャラリーがあるかどうかを検出することはより困難です。

それで、テンプレートタグがこのように見えると仮定しましょう:

if ( function_exists( 'my_gallery' ) )
    echo my_gallery( '100' ); // gallery of image from post 100 will be shown

そしてgallery関数は次のようになります(単純化されています)。

function my_gallery( $post_id = '' ) {
    // whole bunch of stuff in here which is returned
}

ギャラリーのスクリプトとスタイルは、次のようになります(簡略化)。

function my_gallery_scripts() {

   wp_register_script( 'my-gallery-js', MY_GALLERY_URL . 'js/my-gallery.js', array( 'jquery' ), '1.0', true );
   wp_register_style( 'my-gallery-css', MY_GALLERY_URL . 'css/my-gallery.css', '', '1.0', 'screen' );

    // need to load these conditionally, but how?
    wp_enqueue_style( 'my-gallery-js' );
    wp_enqueue_script( 'my-gallery-css' );

}
add_action( 'wp_enqueue_scripts', 'my_gallery_scripts' );

私は$ wp_queryの中にグローバル変数を設定するためにmy_gallery()の中でset_query_varを使ってみました。

 function my_gallery( $post_id = '' ) {

    set_query_var( 'has_gallery', true );

    // whole bunch of stuff in here which is returned
}    

ただし問題は、get_query_varアクション内でwp_enqueue_scriptsを使用できないことです。

ですから、次のようにするのが私にとって理想的です。has_galleryを$ wp_queryオブジェクトにロードすると、すべてのページで利用できるようになります(ただし、動作しない場合を除く)。

 function my_gallery_scripts() {

   wp_register_script( 'my-gallery-js', MY_GALLERY_URL . 'js/my-gallery.js', array( 'jquery' ), '1.0', true );
   wp_register_style( 'my-gallery-css', MY_GALLERY_URL . 'css/my-gallery.css', '', '1.0', 'screen' );

    // does not work
    $has_gallery = get_query_var( 'has_gallery' );

    if ( $has_gallery ) {
        wp_enqueue_style( 'my-gallery-js' );
        wp_enqueue_script( 'my-gallery-css' );
    }
}
add_action( 'wp_enqueue_scripts', 'my_gallery_scripts' );

Set_query_varに似たグローバルオプションを設定する別の方法はありますが、私のシナリオでは動作しますか?私は明らかにグローバル変数の使用を避けたいと思います。また、定数を無駄に設定してみました。

2
Andrew

スクリプトの場合、これは非常に簡単です。my_gallery()関数内でエンキューするだけで、フッターに出力されます(ヘッダーが既に渡されているため)。

しかし、スタイルシートは難題です。それらはheadセクションでのみ動作することが想定されており、フッターのエンキューはサポートされていません。

基本的に、関数が呼び出される前に関数が呼び出されたかどうかを知る必要があります。これは与えられた条件に対する簡単な解決策を持っていません。

私はおそらくあなたが記述している形式でこれを達成するためにJSコードからスタイルシートをロードしようとするでしょう。

1
Rarst

私が想像できる最善の方法は(そして、「最速」ではなく、「作業中」であることを意味します)、そのショートコードの存在について投稿内容をチェックすることです。コアのRegex関数を使うことはそれをとても簡単にします。

ステップ1:登録

/**
 * Register the needed assets
 */
add_action( 'wp_enqueue_scripts', 'wpse_105537_register_assets', 0 );
function wpse_105537_register_assests()
{
    wp_register_script(
        'wpse_105537_script',
        // ETC.
    );
    wp_register_style(
        'wpse_105537_style',
        // ETC.
    );
}

ステップ2:エンキュー

/**
 * Enqueue the needed assets if the shortcode is present anywhere
 */
add_action( 'wp_enqueue_scripts', 'wpse_105537_register_assets' );
function wpse_105537_enqueue_assets()
{
    if ( ! wpse_105537_check_content() )
        return;

    wp_enqueue_script( 'wpse_105537_script' );
    wp_enqueue_style( 'wpse_105537_style' );
}

ヘルパー:投稿内容内のショートコードを検索する

このヘルパー関数は最初の一致の後に中止されます。

/**
 * Check if any of the posts has the shortcode in its post_content
 * @return bool
 */
function wpse_105537_check_content()
{
    global $wp_query;

    foreach ( $GLOBALS['wp_query']->posts as $post )
    {
        $pattern = get_shortcode_regex();
        if (
            preg_match_all( '/'. $pattern .'/s', $post->post_content, $matches )
            AND array_key_exists( 2, $matches )
            AND in_array( 'gallery', $matches[2] )
        )
            return true;
    }

    return false;
}
1
kaiser

私はこれをどのようにするかを私は知っています(meta_keyを検索して現在表示されている記事と突き合わせることができます)が、ホームページ(または他のページ)にギャラリーがあるかどうかを検出することはより困難です。

それでメタキーがあるなら、それはもっともっと簡単でしょう:早めにそれをつかみなさい。最初の2つの機能は他の答えから取ることができます。チェック自体は、次の関数に置き換えられます。

/**
 * Check if any of the posts has the needed gallery meta data attached
 * @return bool
 */
function wpse_105537_check_meta()
{
    global $wp_query;

    foreach ( $GLOBALS['wp_query']->posts as $post )
    {
        if ( '' !== get_post_meta( $post->ID, 'your_meta_key', true ) )
            return true;
    }

    return false;
}
0
kaiser