ショートコード[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つの部分にあります::)
global
呼び出しなのかif
ステートメントなのかわからない….前もって感謝します! P
2問あるので2つの答え:)
現在のfunctions.phpが機能せず、すべてのページにスタイルが追加されないのはなぜですか?それがグローバルコールなのかifステートメントなのかわからない….
これらの関数が呼び出される順序のため、機能しません。ショートコードコールバックは、投稿コンテンツのレンダリング中に呼び出されます(ほとんどの場合、the_content
関数呼び出し)。
wp_enqueue_scripts
とwp_head
はどちらもずっと早く呼び出されます:wp_head
はテーマのheader.php
ファイルのどこかにあり、wp_enqueue_scripts
はwp_head
の呼び出し中に呼び出されます。
ページIDなどがわからないと仮定して、上記のショートコードが使用されているページのみのヘッダーにスタイルシートを追加するための最善の方法は何ですか?
私はそのような「最善の」方法があるとは思わない。まったく良い考えではありません。ブラウザはCSSファイルをキャッシュします。あなたがすべてのページに同じCSSを持っているのであれば、ブラウザは一度だけそれを取得します。さまざまなページのCSSファイルが多数ある場合、ブラウザはそれらすべてを取得する必要があります。だから私は全然それをしないでしょう、そしてグローバルCSSファイルにこれらのCSSスタイルを含めます。
このショートコードを使用するページにのみ含める必要がある場合は、(2つの解決策、より良い選択はあなたのものです。2番目の解決策はより良いと思います)...
wp_head
/wp_enqueue_scripts
が呼び出されると、このフックに関数を追加し、選択された投稿をループ処理し、ショートコードが含まれているか確認し、必要に応じてCSSをエンキューできます。 (もちろんそれほど効率的ではありません)。strstr()
やstrpos()
より遅くなる傾向があるので使わないでください。引数を受け入れる必要がある場合は、正規表現に切り替えることができます。投稿が改訂版ではなく、指定されたsave_post
と一致する場合にのみ、post_type
フックを使用してページ上のショートコードを見つけます。
エントリがすでに存在していない限り、autoloadをyesに設定してadd_option()
を使用して、見つかった投稿IDを配列として保存します。それからupdate_option()
を使います。
フックwp_enqueue_scripts
を使用して、add_scripts_and_styles()
関数を呼び出します。
その関数は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');
これは私のために働く:
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/ /
メインクエリが実行された後にアクションにフックして、スタイルとスクリプトをロードする必要があるかどうかを判断できます。
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.
}
これは、 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);
}
}
また、別の変数が追加されたため、データベースオプションとショートコード名に異なる名前を付けることができます。
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を使ってスクリプトをロードしますが、それはあなたのショートコードが埋め込まれている場所によります。
上記のコードで、$タグとショートコードタグを入れ替えます。
あなたの子供のテーマ関数ファイルに追加し、必要ならば条件を変更してください。
私にとってうまくいったはるかに簡単な解決策は、ショートコード関数の外側にスクリプトを登録してから、その関数の中にスクリプトをエンキューすることでした。それから、あなたのショートコードを使ってページにスクリプトをロードするだけです。
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が有効でない可能性があります。私の場合、それは問題ではありませんでした。
あなたは単純にこれのようにそれをすることができます:
// 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);
私はそれをテストしました、そしてそれはうまくいきます。