получить атрибуты/часть шорткода галереи
Я пытаюсь захватить все идентификаторы изображений, связанные с шорткодом [галерея], которые перечислены как исключить. Например: если в моем сообщении есть [gallery exclude="1,2,3"]
, я хотел бы получить переменную, которая будет повторять такой echo $excludes;
результат 1,2,3
спасибо за любую помощь, которую вы можете предложить.
3 answers
Задача
Это не так просто, как кажется на первый взгляд. Основная проблема заключается в том, что вы можете определить свой собственный шорткод [gallery]
и просто переопределить значение по умолчанию. На самом деле это то, что делают некоторые темы (вините в этом авторов ThemeForest!). В этом случае простое подключение к post_gallery
не будет работать в каждом случае.
Недостатки для post_gallery
Проблема в том, что как шорткод, так и основной обратный вызов могут быть переопределены, и поэтому каждый обратный вызов будет просто быть нокаутированным.
Недостатки для the_content
Если вы переключаетесь на другой фильтр и берете необработанный вывод, вам придется иметь дело (в другой раз) с регулярным выражением. Это медленно и в основном будет непросто.
Так что же теперь делать? Легко. Взаимодействуйте с global $shortcode_tags
. Он содержит обратный вызов в качестве второго аргумента, так что на самом деле не так уж сложно определить, в каком случае мы находимся. Тогда мы можем просто переключаться по требованию. Таким образом, у нас есть прекрасный баланс между надежностью и производительность.
Создайте базовый плагин
Вот плагин, который определяет класс abstract
(тот, который должен получить extend
ed для работы). Есть три вещи, которые нуждаются в определении в дочернем классе:
-
$part
- деталь, которую вы хотите получить -
$type
- тип соответствия, который вам нужен. Допустимыми являютсяdigit/alphanumeric/alpha
-
process_atts()
- метод, который обрабатывает ваши выходные данные - все, что вы хотите сделать с результатом
Просто загрузите это через 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
, а затем запускает метод parents __construct()
для извлечения атрибутов.
Затем вам нужно определить, какие атрибуты вы хотите получить (см. Свойства классов $part
и $type
, которые уже по умолчанию соответствуют тому, что вы просили).
Последние два решения, которые вам нужно принять, это
- Что я хочу сделать со своим результатом? См.
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;
Измените то, что вам нужно, а затем еще раз: Просто загрузите это через FTP в свой папку плагинов и активируйте.
Если вам также нужно отобразить содержимое на той же странице, как насчет использования фильтра 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 '';
}
Мне потребовалось некоторое время, чтобы найти решение, которое сработало для меня, но, поскольку все, что я искал, - это ограниченный список идентификаторов вложений, связанных с определенным атрибутом, таким как exclude
или hide
, это сработало для меня:
# 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;