ページによってはサイドバーに画像などのコンテンツを表示する必要があります。ページは動的に追加され、サイドバーに表示する必要がある情報はページごとに異なります。だから私は何がどこに行くのか予測することはできません。つまり、ページのコンテンツを通常どおりに(必要なすべてのショートコードを付けて)、次にページの最後に、そのページのサイドバーに表示する必要があるすべての情報を含むショートコードを付けます。
私はそれが「選択的に」ショートコードを表示することが可能であるかどうか疑問に思いました。
たとえば、特定のショートコード([sc]
と呼びましょう)をページコンテンツ内で指定します。さて、そのページのコンテンツを表示するとき、私はその特定の[sc]
ショートコードを抑制したいのですが、そのページのサイドバーからそれを表示したいです。ページのコンテンツには他のショートコードがあります。私は特定の[sc]
ショートコードを選択的に表示し、他のものを通常通りに処理したいだけです - すなわち、他のショートコードはページのコンテンツ内で処理されます。
それは可能ですか?そしてどうやって?
ショートコードハンドラは何も返す必要はなく、後でサイドバーウィジェットで読み込んだグローバル変数を変更するだけです。あなたのサイドバーがあなたの投稿内容の後に表示されているなら(それが正しいサイドバーであるならば最も可能性が高いです)、あなたは何の問題もなくこれをすることができます。投稿コンテンツの前にサイドバーが表示される場合はもっと複雑です。ウィジェットが呼び出されたときに出力バッファリングを開始し、ページの残りの部分が表示されるまで待ってから、ショートコードコンテンツで何かをして出力バッファをフラッシュします。
ショートコードの内容を投稿ではなくフッターに表示する単純な「概念実証」:
$wpse13925_shortcode_content = array();
add_shortcode( '13925', 'wpse13925_shortcode' );
function wpse13925_shortcode( $shortcode_attr, $shortcode_content )
{
$GLOBALS['wpse13925_shortcode_content'][] = $shortcode_content;
return '';
}
add_action( 'wp_footer', 'wpse13925_footer' );
function wpse13925_footer()
{
var_dump( $GLOBALS['wpse13925_shortcode_content'] );
}
私の解決策はJan Fabry's
の回答に基づいています。ウィジェットはありませんが、単純なテンプレートファイルがあります。
それで、私がしたことは以下です:
ページのコンテンツ自体のサイドバーに表示する必要があるすべての情報を[sidebar_content]
ショートコードで囲んで指定しました。
Functions.phpに以下の関数を指定しました。これは[sidebar_content]
のすべての内容を展開しますが、何も表示しませんが、代わりにグローバル変数に保存します。
global $sidebar_content;
add_shortcode("sidebar_content", "my_sidebar_content");
function my_sidebar_content($atts, $content = null){
global $sidebar_content;
if( !empty($content) ){
$sidebar_content = do_shortcode($content);
}
return "";
}
sidebar.php
にあります。次のようなコードがあります。
global $sidebar_content;
if( isset($sidebar_content) && !empty($sidebar_content) ){
echo $sidebar_content;
}
コンディショナルタグとdo_shortcodeを使用できます。 http://codex.wordpress.org/Function_Reference/do_shortcode
http://codex.wordpress.org/Conditional_Tags
12のIDを持つ単一ページの簡単な例。
if is_single(12){
do_shortcode('[shortcode]');
}
代わりにこのショートコードを自分で書いた場合は、[shortcode('page=5, 6, 7', 'category', 'exclude=posts', 'whatever')]
のように表示パラメータを与える関数を作成できます。
たとえば、sc_no_show
という名前のカスタムフィールドを作成し、それにtrueの値を指定するなど、カスタムフィールドに基づいて行うことができます。それからあなたのショートコード関数で、このようなことをしてください:
function what_ever(){
global $post;
$no_show = get_post_meta($post->ID,'sc_no_show',true);
if ($no_show)
return '';
//add your normal shortcode stuff here
}
すべてのページまたは投稿に、true
という値を持つsc_no_show
という名前のカスタムフィールドがあります。
ショートコードがフラグを立て、追加のアクションを実行して最初にそのショートコードのコンテンツを削除し、次にセカンダリアクションを実行してサイドバーでそのショートコードを実行する場合、いくつかの適切に配置されたアクションを使用してショートコードを先読みできます。それに加えて、サイドバーファイル内に独自の単純なアクションを作成し、ショートコードを印刷する必要があるときにそれをフックします。
フォローしていませんか?あなたを非難しないでください、私は常にアイデアを説明するのが得意ではないので、ここにコード形式の例を示します.
まず、ショートコードコンテンツを表示するサイドバー内に、次のようなものを追加します。
<?php do_action( 'special_shortcode_content' ); ?>
これで、フラグが設定されたときにフックできるアクションができました。
次に、投稿をスキャンする必要があります。ループが発生する前に、特定のショートコードの存在を確認します。例に従って[sc]
を使用し、the_posts
にフックすることでこれを実行できます。グローバルを使用するよりも、コードをクラスにラップするだけで、フラグとして機能するクラス変数をクラス内で定義することを好みます。
class Page_Shortcode_to_Sidebar {
private $has_shortcode = false;
public function __construct() {
if( is_admin() )
return;
add_action( 'the_posts', array( $this, 'check_for_shortcode' ) );
add_filter( 'the_content', array( $this, 'remove_shortcode' ), 1 );
}
public function check_for_shortcode( $posts ) {
if( empty( $posts ) )
return $posts;
if( !is_page() )
return $posts;
foreach( $posts as $post ) {
if( !stripos( $post->post_content, '[sc]' ) )
continue;
$this->has_shortcode = true;
}
return $posts;
}
public function remove_shortcode( $content ) {
if( !$this->has_shortcode )
return $content;
$content = str_replace( '[sc]', '', $content );
add_action( 'special_shortcode_content', array( $this, 'do_shortcode' ) );
return $content;
}
public function do_shortcode() {
?>
<li><?php do_shortcode('[sc]'); ?></li>
<?php
}
}
$Page_Shortcode_to_Sidebar = new Page_Shortcode_to_Sidebar;
基本的にこれが起こるのは..
the_posts
のコールバックは、ショートコードがないかどうかを確認します(見つかった場合)。the_content
のコールバックは後で実行され、フラグが設定されているかどうかがチェックされます。作成した独自のショートコードを参照しており、この方法で使用している場合..
[sc]something[/sc]
..その後、投稿コンテンツからショートコードコンテンツを取り除くために、よりスマートなものが必要になります。
それがそのように使用されていない場合、私が上で提供したものはうまく仕事をするはずです。
それが役立つことを願っています.. :)