除外としてリストされている[gallery]ショートコードに関連付けられているすべての画像IDを取得しようとしています。例えば:私の投稿が[gallery exclude="1,2,3"]
であるならば、私はこのecho $excludes;
結果のようにエコーする変数を得たいと思います1,2,3
あなたが提供することができるどんな助けにも感謝します。
解決策を見つけるのには少し時間がかかりましたが、探しているのはexclude
やhide
のような特定の属性に関連付けられた添付ファイルIDの区切りリストだけだったので、これは私には役に立ちました。
# Grab the list of "hide" attribute
$regex_pattern = get_shortcode_regex();
preg_match ('/'.$regex_pattern.'/s', $post->post_content, $regex_matches);
if ($regex_matches[2] == 'gallery') :
$attribureStr = str_replace (" ", "&", trim ($regex_matches[3]));
$attribureStr = str_replace ('"', '', $attribureStr);
// Parse the attributes
$defaults = array (
'hide' => '1',
);
$attributes = wp_parse_args ($attribureStr, $defaults);
if (isset ($attributes["hide"])) :
$excludeID = get_post_thumbnail_id() . ',' . $attributes["hide"];
else :
$excludeID = get_post_thumbnail_id();
endif;
endif;
一見するとそれほど簡単ではありません。主な問題はあなたがあなた自身の[gallery]
ショートコードを定義しそして単にデフォルトを上書きすることができるということです。実際にそれはいくつかのテーマがしていることです(あなたがThemeForest作家を非難する!)この場合、単にpost_gallery
にフックするだけではうまくいきません。
post_gallery
の欠点問題は、ショートコードとコアコールバックの両方が上書きされる可能性があるため、すべてのコールバックが単純にノックアウトされることです。
the_content
の欠点別のフィルタに切り替えて生の出力を取得する場合は、(別の時期に)Regexを処理する必要があります。これは遅く、ほとんど単純ではありません。
だから今何をする?簡単です。 global $shortcode_tags
とやり取りしてください。これはコールバックを2番目の引数として保持しているので、実際にどちらのケースであるかを判断するのはそれほど難しくありません。それから私達は単に要求に応じて切り替えることができます。このようにして、信頼性とパフォーマンスの間で優れたバランスを取ります。
これがabstract
クラスを定義するプラグインです(動作するためにはextend
edを取得する必要があります)。子クラスで定義が必要なものが3つあります。
$part
- 取得したい部分$type
- あなたが必要とするマッチの種類。有効なのはdigit/alphanumeric/alpha
ですprocess_atts()
- あなたの出力を処理するメソッド - あなたが結果に対して何をしたいとしてもこれを(S)FTP経由であなたのプラグインフォルダにアップロードして起動してください。
<?php
/** Plugin Name: (#70451) »kaiser« Get Gallery attributes (Base) */
if ( ! class_exists( 'wpse70451_extract_gallery_atts' ) )
{
abstract class wpse70451_extract_gallery_atts
{
public $atts = array();
public $error;
// Must get defined in extending class
public $part;
public $type;
public static function init()
{
is_null( self :: $instance ) AND self :: $instance = new self;
return self :: $instance;
}
public function __construct()
{
! isset( $this->part ) AND new WP_Error();
add_action( 'loop_start', array( $this, 'error_handler' ) );
// The value of the array is the callback fn name
// If it's the default, then we're on the safe side,
// as the core fn is no pluggable and can't get overridden.
if ( 'gallery_shortcode' === $GLOBALS['shortcode_tags'] )
{
add_filter( 'post_gallery', array( $this, 'get_gallery_atts' ), 0, 2 );
}
// Else we have to go with a slower regex
else
{
add_filter( 'the_content', array( $this, 'get_gallery_ids' ), 0 );
}
}
public function error_handler()
{
if (
! in_array(
$this->type
,array(
'digit'
,'alphanumeric'
,'alpha'
)
)
OR ! empty( $this->type )
)
return new WP_Error(
'invalid_type'
,__( 'Invalid type set.', 'wpse70451_textdomain' )
,__FILE__
);
}
public function __toString()
{
$is_error = $this->error;
if ( ! is_wp_error( $is_error ) )
return;
// No error message for Guests or Subscribers
// Assuming that no one has activated caching plugins when debugging
// and not set WP_DEBUG to TRUE on a live site
if (
! is_user_logged_in()
AND ! current_user_can( 'edit_posts' )
AND ( ! defined( 'WP_DEBUG' ) OR ! WP_DEBUG )
)
return '';
// Error output for development
return "{$is_error->get_error_message( 'invalid_type' )}: {$is_error->get_error_data()}";
}
public function get_gallery_ids( $content )
{
$pattern = get_shortcode_regex( $content );
preg_match_all( "/{$pattern}/s", $content, $matches );
$atts = explode( " ", array_shift( $matches[3] ) );
foreach ( $atts as $att )
{
if ( strstr( $att, $this->part ) )
break;
}
preg_match_all( $this->get_regex( $this->type ), trim( $att ), $atts );
$this->atts = array_filter( $atts );
return $content;
}
// Build pattern
public function get_regex( $type )
{
switch ( $type )
{
case 'digit' :
$pattern_atts = '/(\d*)/';
break;
case 'alphanumeric' :
$pattern_atts = '/([A-Za-z0-9]*)/';
break;
case 'alpha' :
$pattern_atts = '/([A-Za-z]*)/';
break;
default :
// Add a method name `get_pattern()` to the extending class
// to work with a custom regex pattern.
if ( method_exists( $this, 'get_pattern' ) )
{
$pattern_atts = $this->get_pattern();
break;
}
$pattern_atts = $this->get_regex( 'alphanumeric' );
break;
}
return $pattern_atts;
}
public function get_gallery_atts( $content, $atts )
{
$this->atts = $atts[ $this->part ];
// Allow overrides to trigger
// at this point we already got what we need
return $content;
}
// Must get defined in extending class
public abstract function process_atts() {}
} // END Class
} // endif;
これが実際の処理プラグインです。まずそれ自身をinit
フックに静的にフックしてから、両親の__construct()
メソッドを実行して属性を取得します。
次に、どの属性を取得したいのかを定義する必要があります(クラスプロパティ$part
および$type
を参照してください。これらはすでにデフォルトの値になっています)。
あなたがする必要がある最後の2つの決定は、
process_atts()
を参照してください。__construct()
およびprocess_atts()
がフックされている場所を参照してください。それはそれと同じくらい簡単です。
カスタム正規表現が必要な場合は、拡張クラスにget_regex()
というメソッドを、カスタムパターンにreturn
を追加するだけです。 $type
を空の文字列''
に設定すれば準備完了です。
<?php
/** Plugin Name: (#70451) »kaiser« Get Gallery excludes */
if ( ! class_exists( 'wpse70451_extract_gallery_excludes' ) )
{
add_action( 'init', array( 'wpse70451_extract_gallery_excludes', 'init' ) );
final class wpse70451_extract_gallery_excludes extends wpse70451_extract_gallery_atts
{
public static $instance;
public $part = 'exclude';
public $type = 'digit';
public static function init()
{
is_null( self :: $instance ) AND self :: $instance = new self;
return self :: $instance;
}
public function __construct()
{
parent :: __construct();
// Example hook: `loop_end`
add_action( 'loop_end', array( $this, 'process_atts' ) );
}
public function process_atts()
{
$markup = '';
// Do something with $this->atts;
return print $markup;
}
} // END Class
} // endif;
必要なものを変更してから、もう一度(S)FTP経由でpluginsフォルダにアップロードしてアクティブにしてください。
同じページにコンテンツを表示する必要がある場合は、post_gallery
フィルタを使用してどうでしょうか。その場合は、正規表現は必要ありません。
add_filter('post_gallery', 'gallery_shortcode_excludes', 10, 2);
function gallery_shortcode_excludes($content, $attr) {
$excludes = $attr['excludes'];
// maybe also save it in some global/class/static variable
// return empty string to let wordpress continue to the shortcode output
return '';
}