ショートコードとは
バージョン2.5から、WordPress開発者は「ショートコードAPI」の概念を導入しました。 この機能により、サイトのページまたはブログエントリでマクロコードを作成および使用できます。 たとえば、シンプルで短いエントリを使用すると、ページにフォトギャラリー全体が追加されます。
WordPressのドキュメントから、ショートコードの詳細を読んだり、簡単なショートコードを作成する方法を学ぶことができます 。
この記事では、より複雑なショートコードを作成し、作成時に最も一般的な問題を解決する方法を示したいと思います。
- サードパーティのスクリプトを接続し、ページにショートコードがある場合にのみ起動します。
- 階層化されたショートコード。
- 複合ショートコード。
- ショートコードのネスティング。
土壌の準備
何かを作成する前に、ファイルを配置するためのオプションを提案します。
/
/含まれるもの/
shortcodes.php
...
functions.php
ほとんどすべてのマニュアルでは、functions.phpファイルにショートコードを直接作成することを提案しています。 私はすぐに言います:私はこのアプローチの反対者です。 代わりに、すべてのショートコードを個別のファイル(/shortcodes.phpを含む)に入れ、それをfunctions.phpに1行で接続することを強くお勧めします。 これにより、functions.phpが大幅にオフロードされ、コードが読みやすくなります。
注 :もちろん、WordPressはrequireを介したファイルの接続をサポートしていますが、これを行うことはあまりお勧めしません。 代わりに、 get_template_part()を使用することをお勧めします。
スクリプト接続
多くの初心者開発者はこの間違いを頻繁に犯します-ショートコードを宣言するときに特定のショートコードの操作に必要なスクリプトがすぐに含まれます。 つまり、このショートコードがページ上にない場合でも、スクリプトは常にロードされます。
そのような実装の例:
function foobar_func( $atts ) { return "foo and bar"; } add_shortcode( 'foobar', 'foobar_func' ); function foo_script () { wp_register_script( 'foo-js', get_template_directory_uri() . '/includes/js/foo.js'); wp_enqueue_script( 'foo-js' ); } add_action( 'wp_enqueue_scripts', 'foo_script');
これは完全に機能するバージョンですが、スクリプトはすべてのページでロードされます(必要ない場合でも)(つまり、ショートコードはありません)。
このような状況を回避するために、次のアプローチを使用することを提案します。
- ショートコードを別のクラスとして定義します。
- 特定のショートコードがページ上にあるかどうかを判断するフラグを追加します。
- ショートコードの存在フラグによってのみスクリプトをダウンロードします。
それだけです...
そのような実装の例:
class foobar_shortcode { static $add_script; static function init () { add_shortcode('foobar', array(__CLASS__, 'foobar_func')); add_action('init', array(__CLASS__, 'register_script')); add_action('wp_footer', array(__CLASS__, 'print_script')); } static function foobar_func( $atts ) { self::$add_script = true; return "foo and bar"; } static function register_script() { wp_register_script( 'foo-js', get_template_directory_uri() . '/includes/js/foo.js'); } static function print_script () { if ( !self::$add_script ) return; wp_print_scripts('foo-js'); } } foobar_shortcode::init();
前の実装とは異なり、このショートコードは初期化されますが、すべてのスクリプトはページにショートコードがある場合にのみロードされます。
ネストされたショートコード
初心者の開発者が遭遇する可能性のある問題がいくつかあります。
- マルチレベルショートコード(複数で構成される)を作成します。
- 同じショートコード内でショートコードを使用します。
より詳細に。
階層化されたショートコードを作成する
問題は、このようなショートコードはいくつかの小さなショートコードで構成されており、それらを個別のショートコードとして使用する可能性を防ぐ必要があることです(必要な場合を除く)。
たとえば、価格表を作成するショートコードを考えてみましょう。 これを行うには、3つの個別のショートコードを準備します。
[価格]
-[プランタイトル= 'プラン1'価格= '99 ']
-[オプション]オプション1 [/オプション]
-[オプション]オプション2 [/オプション]
-[オプション] ... [/オプション]
-[/プラン]
-[プランのタイトル=「プラン2」の価格=「499」]
-[オプション]オプション1 [/オプション]
-[オプション]オプション2 [/オプション]
-[オプション] ... [/オプション]
-[/プラン]
...
[/価格]
この例では、3つのショートコードを使用します:[価格] [計画] [オプション]
add_shortcode( 'price'、 'price_code');
add_shortcode( 'plan'、 'plan_code');
add_shortcode( 'option'、 'option_code');
内部ショートコードが別個のものとして使用されるのを防ぐために、次のスキームが提案されています。
価格->ページごとのコード出力
計画->データ収集
オプション->データの取得
つまり、コードは外部ショートコードでのみページに出力されますが、内部ショートコードは受信したデータを返すだけです。 そのような実装の例を以下に示します。
外部ショートコードの機能の説明:
function price_code ($atts, $content) { // $GLOBALS['plan-count'] = 0; $GLOBALS['plans'] = array(); // do_shortcode($content); // HTML $output = '<div class="price">'; if(is_array($GLOBALS['plans'])) { foreach ($GLOBALS['plans'] as $plan) { $planContent = '<div class="plan">'; $planContent .= $plan; $planContent .= '</div>'; $output .= $planContent; } } $output .= '</div>'; // HTML return $output; }
内部ショートコードの機能の説明:
function plan_code ($atts, $content) { // extract(shortcode_atts(array( 'title' => '', // Plan title name 'price' => '0', // Plan price ), $atts)); // HTML: $plan_title = '<div class="plan-title">'; $plan_title .= ' <p>'.$title.'</p>'; $plan_title .= '</div>'; // HTML: $f_price = round(floatval($price), 2); $f_price = ($f_Price > 0) ? $f_Price : 0; $s_price = '$'.$f_Price; $price_plan = '<div class="plan">'; $price_plan .= ' <p class="price-sum">'.$s_price.'</p>'; $price_plan .= ' <small class="price-text">'.$text.'</small>'; $price_plan .= '</div>'; // $GLOBALS['plan-options-count'] = 0; $GLOBALS['plan-options'] = array(); // do_shortcode($content); // HTML: $plan_options = '<div class="plan-options">'; if (is_array($GLOBALS['plan-options'])) { foreach ($GLOBALS['plan-options'] as $option) { $plan_options .= $option; } } $s_OptionsDiv.= '</div>'; // HTML: $plan_div = $plan_title; $plan_div .= $price_plan; $plan_div .= $plan_options; // $i = $GLOBALS['plan-count'] + 1; $GLOBALS['plans'][$i] = $plan_div; $GLOBALS['plan-count'] = $i; // return true; } function option_code ($atts, $content) { // HTML $plan_option = '<div class="price-option">'; $plan_option .= ' <p class="price-option-text">'.do_shortcode($content).'</p>'; $plan_option .= '</div>'; // $i = $GLOBALS['plan-options-count'] + 1; $GLOBALS['plan-options'][$i] = $plan_option; $GLOBALS['plan-options-count'] = $i; // return true; }
このアプローチでは、ショートコードはコレクションでのみ機能します。つまり、正しく使用すると、画面に何も表示されなくなります(したがって、何も壊れません)。
もちろん、このショートコードを最適化して改善することはできますが、それでも私はなんとか主なアイデアを実証できたと思います。
繰り返し可能なショートコード
問題はこれです:ショートコード内で同じショートコードを使用する必要があります。 私の実践で最も一般的な例は、列を作成するためのショートコードです。 つまり、たとえば、列を使用してページを2つの部分に分割し、最初の列をさらに2列に分割する必要があります。
[column_half]
[column_half]コンテンツ[/ column_half]
[column_half]コンテンツ[/ column_half]
[/ column_half]
[column_half]コンテンツ[/ column_half]
残念ながら、WordPressの場合、このネスティングは既に困難です。 2番目のコンテンツでは、レイアウトがばらばらになります。 これは、ショートコードを開くと、WordPressがこのショートコードの2番目の(閉じている)部分、つまり この例では、最初のネストされたショートコードで最初の列が閉じられます。
残念ながら、この問題を解決するための新しいショートコードを追加する以外のオプションはありません。 ただし、関数を書き換えても意味がありません。ショートコードを既存の関数に初期化するだけです。
add_shortcode( 'column_half', 'column_half_code' ); add_shortcode( 'column_half_inner', 'column_half_code' ); function column_half_code ( $atts, $content ) { return "<div class='col-lg-6'>".do_shortcode($content)."</div>"; } : [column_half] [column_half_inner] Content [/column_half_inner] [column_half_inner] Content [/column_half_inner] [/column_half] [column_half] Content [/column_half]
おわりに
この記事では、私自身が遭遇した最も一般的な問題を調べました。 特定の問題に対して独自の解決策を追加、修正、または提案するものがある場合は、この記事へのコメントを書くことをheしないでください。
投稿者:Dmitry Kabakov、シニアフロントエンド開発者。