WordPress CMSでショートコードを作成する





ショートコードとは


バージョン2.5から、WordPress開発者は「ショートコードAPI」の概念を導入しました。 この機能により、サイトのページまたはブログエントリでマクロコードを作成および使用できます。 たとえば、シンプルで短いエントリを使用すると、ページにフォトギャラリー全体が追加されます。



WordPressのドキュメントから、ショートコードの詳細を読んだり、簡単なショートコードを作成する方法を学ぶことができます



この記事では、より複雑なショートコードを作成し、作成時に最も一般的な問題を解決する方法を示したいと思います。

  1. サードパーティのスクリプトを接続し、ページにショートコードがある場合にのみ起動します。
  2. 階層化されたショートコード。

    • 複合ショートコード。
    • ショートコードのネスティング。






土壌の準備


何かを作成する前に、ファイルを配置するためのオプションを提案します。



/

/含まれるもの/

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');
      
      







これは完全に機能するバージョンですが、スクリプトはすべてのページでロードされます(必要ない場合でも)(つまり、ショートコードはありません)。



このような状況を回避するために、次のアプローチを使用することを提案します。



  1. ショートコードを別のクラスとして定義します。
  2. 特定のショートコードがページ上にあるかどうかを判断するフラグを追加します。
  3. ショートコードの存在フラグによってのみスクリプトをダウンロードします。




それだけです...



そのような実装の例:



 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、シニアフロントエンド開発者。



All Articles