web-dev-qa-db-ja.com

特定のショートコードを持つページにのみスタイルシートを追加する方法

ショートコード[make-me-a-map]が使用されているページで関数を実行しています。それはページにジャバスクリプトをエンキューし、地図を作ります。その部分は問題なく動作します(woot!)が、スタイルシートをそれらのページだけに同様の方法で追加するのに問題があります。

functions.php(現在)

add_shortcode("make-me-a-map", "create_new_map");
add_action("wp_head", "style_my_new_map");

function create_new_map () {
    global $new_map_called_for;
    $map_called_for = true;

    wp_register_script('make-a-new-map', get_template_directory_uri() . '/js/new-map.js', array('jquery'), '0.1', true);
    wp_enqueue_script('make-a-new-map');
    }

function style_my_new_map() {
    global $new_map_called_for;
    if ($new_map_called_for == true) {
        $tDir = get_template_directory_uri();

        // Echo stylesheets because wp_register_style & wp_enqueue_style don't work atm
        // And add_action('wp_enqueue_script', 'style_my_new_maps') with those functions would add style to all pages
        // Not just the ones with [make-me-a-map] shortcode
        echo "<link rel='stylesheet' href='", $tDir, "/css/new-map.css' />", PHP_EOL;

        // Echo Javascript straight to page (couldn't do it with wp_enqueue_script) to let js code know the template directory
        echo '<script type="text/javascript">var templateDir = "', get_template_directory_uri(), '";</script>', PHP_EOL;
        $map_called_for = false;
    }
}

残念ながらこれはうまくいっていないようです。スタイルはすべてのページに追加されています。

このバグ はまだこれらの関数からフッターに<Link />タグを追加しているので、wp_register_style&wp_enqueue_styleを使用しませんでした。

add_action("wp_enqueue_scripts", "style_my_new_map")の代わりにadd_action('wp-head', "style_my_new_map")を使用することもできますが、確認して確認できる限り、違いはありませんか。それでも、すべてのページにスタイルシートを追加します。

だから私の質問は実際には2つの部分にあります::)

  1. 現在のfunctions.phpが機能せず、すべてのページにスタイルが追加されないのはなぜですか?それがglobal呼び出しなのかifステートメントなのかわからない….
  2. ページIDなどがわからないと仮定して、上記のショートコードが使用されているページのみのヘッダーにスタイルシートを追加するための最善の方法は何ですか?

前もって感謝します! P

7
Padraic

2問あるので2つの答え:)

現在のfunctions.phpが機能せず、すべてのページにスタイルが追加されないのはなぜですか?それがグローバルコールなのかifステートメントなのかわからない….

これらの関数が呼び出される順序のため、機能しません。ショートコードコールバックは、投稿コンテンツのレンダリング中に呼び出されます(ほとんどの場合、the_content関数呼び出し)。

wp_enqueue_scriptswp_headはどちらもずっと早く呼び出されます:wp_headはテーマのheader.phpファイルのどこかにあり、wp_enqueue_scriptswp_headの呼び出し中に呼び出されます。

ページIDなどがわからないと仮定して、上記のショートコードが使用されているページのみのヘッダーにスタイルシートを追加するための最善の方法は何ですか?

私はそのような「最善の」方法があるとは思わない。まったく良い考えではありません。ブラウザはCSSファイルをキャッシュします。あなたがすべてのページに同じCSSを持っているのであれば、ブラウザは一度だけそれを取得します。さまざまなページのCSSファイルが多数ある場合、ブラウザはそれらすべてを取得する必要があります。だから私は全然それをしないでしょう、そしてグローバルCSSファイルにこれらのCSSスタイルを含めます。

このショートコードを使用するページにのみ含める必要がある場合は、(2つの解決策、より良い選択はあなたのものです。2番目の解決策はより良いと思います)...

  1. これらのスタイルをインラインスタイルとして追加できます。何度も含めないように注意してください。だからあなたのショートコードでそれらを出力し、それらが一度だけ印刷されることを保証しなさい。
  2. 投稿はすでに選択されているので、wp_head/wp_enqueue_scriptsが呼び出されると、このフックに関数を追加し、選択された投稿をループ処理し、ショートコードが含まれているか確認し、必要に応じてCSSをエンキューできます。 (もちろんそれほど効率的ではありません)。
1

ショートコードを使用してスクリプトとスタイルを動的にロードする

利点

  • ショートコードが呼び出されるたびにすべての投稿を検索しません。
  • ショートコードがページ上にある場合にのみ、スタイルやスクリプトを動的に追加することができます。
  • 正規表現はstrstr()strpos()より遅くなる傾向があるので使わないでください。引数を受け入れる必要がある場合は、正規表現に切り替えることができます。
  • ファイル呼び出しを削減

コードの説明

  1. 投稿が改訂版ではなく、指定されたsave_postと一致する場合にのみ、post_typeフックを使用してページ上のショートコードを見つけます。

  2. エントリがすでに存在していない限り、autoloadをyesに設定してadd_option()を使用して、見つかった投稿IDを配列として保存します。それからupdate_option()を使います。

  3. フックwp_enqueue_scriptsを使用して、add_scripts_and_styles()関数を呼び出します。

  4. その関数はget_option()を呼び出して、ページIDの配列を取得します。現在の$page_id$option_id_arrayにある場合、それはスクリプトとスタイルを追加します。

注意してください。 私はOOP名前空間クラスからコードを変換したので、見落としがあるかもしれません。私がそうしたら私にコメントで知らせなさい。

コード例:ショートコードオカレンスの検索

function find_shortcode_occurences($shortcode, $post_type = 'page')
{
    $found_ids = array();
    $args         = array(
        'post_type'   => $post_type,
        'post_status' => 'publish',
        'posts_per_page' => -1,
    );
    $query_result = new \WP_Query($args);
    foreach ($query_result->posts as $post) {
        if (false !== strpos($post->post_content, $shortcode)) {
            $found_ids[] = $post->ID;
        }
    }
    return $found_ids;
}

function save_option_shortcode_post_id_array( $post_id ) {
    if ( wp_is_post_revision( $post_id ) OR 'page' != get_post_type( $post_id )) {
        return;
    }
    $option_name = 'yourprefix-yourshortcode';
    $id_array = find_shortcode_occurences($option_name);
    $autoload = 'yes';
    if (false == add_option($option_name, $id_array, '', 'yes')) update_option($option_name, $id_array);
}

add_action('save_post', 'save_option_shortcode_id_array' );

コード例:スクリプトとスタイルを動的に含むショートコード

function yourshortcode_add_scripts_and_styles() {
    $page_id = get_the_ID();
    $option_id_array = get_option('yourprefix-yourshortcode');
    if (in_array($page_id, $option_id_array)) {
        wp_enqueue_script( $handle, $src, $deps, $ver, $footer = true );
        wp_enqueue_style( $handle, $src , $deps);
    }
}

add_action('wp_enqueue_scripts', 'yourshortcode_add_scripts_and_styles');
9
CommandZ

これは私のために働く:

function register_my_css () {
    wp_register_style('my-style', plugins_url('styles.css', __FILE__));
}

function register_my_scripts () {
    wp_register_script('my-script', plugins_url('scripts.js', __FILE__));
}

// only enqueue the scripts / styles when the short code is called
function do_my_shortcode () {
    wp_enqueue_style('my-style');
    wp_enqueue_script('my-script');

    // do short code stuff...
}

// register css
add_action('wp_enqueue_scripts', 'register_my_css');

// register javascript
add_action('wp_enqueue_scripts', 'register_my_scripts');

// register shortcode
add_shortcode('my-shortcode', 'do_my_shortcode');

ここでより多くの情報: http://mikejolley.com/2013/12/sensible-script-enqueuing-shortcodes/ /

2
benedict_w

メインクエリが実行された後にアクションにフックして、スタイルとスクリプトをロードする必要があるかどうかを判断できます。

add_action('template_include', 'custom_template_include');
function custom_template_include($template) {
    if (is_single() || is_page()) {
          global $post;
          if (has_shortcode($post->post_content, 'your_short_code')) {
              add_action('wp_enqueue_scripts, 'custom_enqueue_scripts');
          }
    } 
}

function custom_enqueue_scripts() {
    //Enqueue your stuff here. 
}
1
Lucas Stark

ショートコードを使用してスクリプトとスタイルを動的にロードする

これは、 Commandz 上記で提供されているソリューションの拡張コードです。

私は彼の方法がデータベースオプションがほとんどすべてのフックで利用可能であるので最も良くそしてより実行可能であることを見出しました。

現在の投稿コンテンツに対して、すべての投稿を通過するのではなく、ショートコード only の出現を見つけるように変更されました。投稿数が多い場合は遅くなる可能性があります。

save_postアクションから関数find_shortcode_occurences()に別の$ post_id変数を渡した後、ここで2行で変更されます

if( !empty($post_id) ) {
    $args['posts__in'] = $post_id; 
}

両機能のコードを変更

function find_shortcode_occurences($shortcode, $post_id='', $post_type = 'page') {
    $found_ids = array();
    $args         = array(
        'post_type'   => $post_type,
        'post_status' => 'publish',
        'posts_per_page' => -1,
    );

    if( !empty($post_id) ) {
        $args['posts__in'] = $post_id; 
    }

    $query_result = new WP_Query($args);
    foreach ($query_result->posts as $post) {
        if (false !== strpos($post->post_content, $shortcode)) {
            $found_ids[] = $post->ID;
        }
    }
    return $found_ids;
}

add_action('save_post', 'save_option_for_sppro_pages' );
function save_option_for_sppro_pages( $post_id ) {
    if ( wp_is_post_revision( $post_id ) ) {
        return;
    }
    $option_name = 'database-option';
    $shortcode = 'shortcode-name';
    $id_array = find_shortcode_occurences($shortcode, $post_id);
    $autoload = 'yes';
    if (false == add_option($option_name, $id_array, '', 'yes')) {
        $current_value = get_option($option_name);
        $new_value = array_merge($current_value, $id_array);
        update_option($option_name, $id_array);
    }
}

また、別の変数が追加されたため、データベースオプションとショートコード名に異なる名前を付けることができます。

0
OmAk
add_action( 'wp_enqueue_scripts', 'enqueue_shortcode_styles', 1 );
function enqueue_shortcode_styles() {

    global $post;

    if ( isset($post->post_content) && is_singular(array( 'post','page' ) ) && ! has_shortcode( $post->post_content, '$tag' ) ) {

    wp_enqueue_style( 'shortcode-styles', get_stylesheet_directory_uri() . '/style.css' );

    }

}

私は has_shortcode を使って$ postの内容をチェックし、wp_enqueue_scriptsを使ってスクリプトをロードしますが、それはあなたのショートコードが埋め込まれている場所によります。

上記のコードで、$タグとショートコードタグを入れ替えます。

あなたの子供のテーマ関数ファイルに追加し、必要ならば条件を変更してください。

0
Dev

私にとってうまくいったはるかに簡単な解決策は、ショートコード関数の外側にスクリプトを登録してから、その関数の中にスクリプトをエンキューすることでした。それから、あなたのショートコードを使ってページにスクリプトをロードするだけです。

wp_register_script('make-a-new-map', get_template_directory_uri() . '/js/new-map.js', array('jquery'), '0.1', true);
wp_register_style('make-a-new-map-style', get_template_directory_uri() . '/css/new-map.css');

add_shortcode("make-me-a-map", "create_new_map");
add_action("wp_head", "style_my_new_map");

function create_new_map () {
   wp_enqueue_script('make-a-new-map');
   wp_enqueue_style('make-a-new-map-style');

   global $new_map_called_for;
   $map_called_for = true;
}

その方法の説明はここで見つけることができます: http://mikejolley.com/2013/12/sensible-script-enqueuing-shortcodes/ /

これはフッターにCSSをロードすることに注意してください。これは望ましくないか、またはW3Cが有効でない可能性があります。私の場合、それは問題ではありませんでした。

0
stellarcowboy

あなたは単純にこれのようにそれをすることができます:

// shortcode hook
add_shortcode("make-me-a-map", "create_new_map");

// shortcode callback
function style_my_new_map() {
    global $new_map_called_for;
    if ($new_map_called_for == true) {
  wp_register_script('make-a-new-map', get_template_directory_uri() . '/js/new-map.js', array('jquery'), '0.1', true);
  wp_enqueue_script('make-a-new-map');

// the rest of your codes
    }
}

スタイルシートにも使えます。最後にスタイルシートをロードするには、次のようにショートコードフックに番号を追加します。

add_shortcode("make-me-a-map", "create_new_map", 9999);

私はそれをテストしました、そしてそれはうまくいきます。

0
KeepMove