У меня есть несколько коротких кодов в сообщении:
[section title="first"] [section title="second"] [section title="third"]
Я хочу извлечь все внешние значения (то есть первую, вторую, третью ) из внешней функции, вот как я пытаюсь сделать:
$pattern = get_shortcode_regex(); preg_match('/'.$pattern.'/s', $post->post_content, $matches); if (is_array($matches) && $matches[2] == 'section') { $attribureStr = str_replace (" ", "&", trim ($matches[3])); $attribureStr = str_replace ('"', '', $attributeStr); $attributes = wp_parse_args ($attributeStr); echo $attributes["title"]; }
Проблема в том, что код извлекает значение только из первого короткого кода. Как заставить его работать для каждого короткого кода в сообщении?
Если доступно, я бы использовал:
shortcode_atts_{$shortcode}
фильтр для сбора атрибутов заданного короткого кода.
Пример:
$text = ' [gallery] [gallery ids="1,2" link="file"] [gallery ids="3"] [caption id="attachment_6" align="alignright" width="300"] '; if( class_exists( 'WPSE_CollectShortcodeAttributes' ) ) { $o = new WPSE_CollectShortcodeAttributes; $out = $o->init( $shortcode = 'gallery', $text )->get_attributes(); print_r( $out ); }
где наш вспомогательный класс определяется как:
class WPSE_CollectShortcodeAttributes { private $text = ''; private $shortcode = ''; private $atts = array(); public function init( $shortcode = '', $text = '' ) { $this->shortcode = esc_attr( $shortcode ); if( shortcode_exists( $this->shortcode ) && has_shortcode( $text, $this->shortcode ) ) { add_filter( "shortcode_atts_{$this->shortcode}", array( $this, 'collect' ), 10, 3 ); $this->text = do_shortcode( $text ); remove_filter( "shortcode_atts_{$this->shortcode}", array( $this, 'collect' ), 10 ); } return $this; } public function collect( $out, $pair, $atts ) { $this->atts[] = $atts; return $out; } public function get_attributes() { return $this->atts; } }
Результат нашего примера:
Array ( [0] => Array ( [0] => ) [1] => Array ( [ids] => 1,2 [link] => file [orderby] => post__in [include] => 1,2 ) [2] => Array ( [ids] => 3 [orderby] => post__in [include] => 3 ) )
поэтому для короткого кода gallery
мы также получаем некоторые дополнительные атрибуты.
Но не все короткие коды поддерживают указанный фильтр. В этом случае вы можете попробовать следующее:
/** * Grab all attributes for a given shortcode in a text * * @uses get_shortcode_regex() * @uses shortcode_parse_atts() * @param string $tag Shortcode tag * @param string $text Text containing shortcodes * @return array $out Array of attributes */ function wpse172275_get_all_attributes( $tag, $text ) { preg_match_all( '/' . get_shortcode_regex() . '/s', $text, $matches ); $out = array(); if( isset( $matches[2] ) ) { foreach( (array) $matches[2] as $key => $value ) { if( $tag === $value ) $out[] = shortcode_parse_atts( $matches[3][$key] ); } } return $out; }
Пример:
$text = ' [gallery] [gallery ids="1,2" link="file"] [gallery ids="3"] [caption id="attachment_6" align="alignright" width="300"][/caption] '; $out = wpse172275_get_all_attributes( 'gallery', $text ); print_r( $out );
с выходом:
Array ( [0] => [1] => Array ( [ids] => 1,2 [link] => file ) [2] => Array ( [ids] => 3 ) )
Надеюсь, вы можете изменить это на свои нужды.