web-dev-qa-db-ja.com

属性/ギャラリーの一部を取得

除外としてリストされている[gallery]ショートコードに関連付けられているすべての画像IDを取得しようとしています。例えば:私の投稿が[gallery exclude="1,2,3"]であるならば、私はこのecho $excludes;結果のようにエコーする変数を得たいと思います1,2,3あなたが提供することができるどんな助けにも感謝します。

2
sosukeinu

解決策を見つけるのには少し時間がかかりましたが、探しているのはexcludehideのような特定の属性に関連付けられた添付ファイル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;
1
sosukeinu

タスク

一見するとそれほど簡単ではありません。主な問題はあなたがあなた自身の[gallery]ショートコードを定義しそして単にデフォルトを上書きすることができるということです。実際にそれはいくつかのテーマがしていることです(あなたがThemeForest作家を非難する!)この場合、単にpost_galleryにフックするだけではうまくいきません。

post_galleryの欠点

問題は、ショートコードとコアコールバックの両方が上書きされる可能性があるため、すべてのコールバックが単純にノックアウトされることです。

the_contentの欠点

別のフィルタに切り替えて生の出力を取得する場合は、(別の時期に)Regexを処理する必要があります。これは遅く、ほとんど単純ではありません。

だから今何をする?簡単です。 global $shortcode_tagsとやり取りしてください。これはコールバックを2番目の引数として保持しているので、実際にどちらのケースであるかを判断するのはそれほど難しくありません。それから私達は単に要求に応じて切り替えることができます。このようにして、信頼性とパフォーマンスの間で優れたバランスを取ります。

ベースプラグインを構築する

これがabstractクラスを定義するプラグインです(動作するためにはextendedを取得する必要があります)。子クラスで定義が必要なものが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つの決定は、

  1. 自分の結果に何をしたいのですか? process_atts()を参照してください。
  2. いつ結果を出力しますか。 __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フォルダにアップロードしてアクティブにしてください。

3
kaiser

同じページにコンテンツを表示する必要がある場合は、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 '';
}
1
Mridul Aggarwal