Intereting Posts

Поддерживает ли WordPress короткий код, вызывающий себя из-за короткого вызова?

Я создал супер-сумасшедшую структуру WordPress, в которой есть миллион и один короткий код, один из которых – это короткий код столбца, который поддерживает параметр count, который позволяет вам определить столбец и соответствующий класс будет добавлен.

Мой короткий код выглядит следующим образом:

add_shortcode('column', 'column_shortcode'); function column_shortcode($atts, $content = '') { extract(shortcode_atts(array( 'count' => 12 ), $atts)); if (stripos($count, '_') === FALSE) { if ((int) $count > 12) { $count = 12; } } $html = '<div class="column-'.$count.' column">'; $html .= do_shortcode($content); $html .= '</div>'; return $html; } 

Однако возникает проблема, когда в колонке используется короткий код столбца, является ли это известной проблемой или WordPress не поддерживает короткие коды с одним и тем же именем, вложенные друг в друга?

По сути, столбец внутри преждевременно закрыт в выпущенном HTML, и я вижу [/ column], завернутый в теги абзаца, которые отображаются на интерфейсе. Однако, если я создаю еще один короткий код и назову его дочерним, используя тот же самый код, что и выше, только черный шрот-код – это только [child] вместо [column], все работает так, как ожидалось.

Вот код из редактора WYSIWYG в моей установке WordPress. Приложение A является идеальным сценарием, я не хочу использовать два разных коротких кода, которые делают то же самое. Приложение B – это то, что работает, просто дублируя короткий код.

Приложение A – не работает

 [column count="9"] [column count="8_9"] Welcome to the site. Who's brave enough to fly into something we all keep calling a death sphere? Well, then good news! It's a suppository. A true inspiration for the children. Ah, computer dating. It's like pimping, but you rarely have to use the phrase "upside your head." [/column] [/column] 

Выставка B – работает

 [column count="9"] [child count="8_9"] Welcome to the site. Who's brave enough to fly into something we all keep calling a death sphere? Well, then good news! It's a suppository. A true inspiration for the children. Ah, computer dating. It's like pimping, but you rarely have to use the phrase "upside your head." [/child] [/column] 

Это известная проблема. Если у вас есть один короткий код внутри другого с таким же именем, синтаксический анализатор wordpress не сможет правильно их обработать. Это также упоминается на странице codex для API короткого кода в рамках ограничений.

На связанной странице. However the parser will fail if a shortcode macro is used to enclose another macro of the same name

Решение, которое я предлагаю, заключается в добавлении дополнительных параметров в основной вызов по короткому коду и в вашей функции короткого кода, рекурсивный вызов себя на основе наличия этих дополнительных параметров

ПРИМЕР

 [column count="9" child="8_9" 8_9_text=" Welcome to the site. Who's brave enough to fly into something we all keep calling a death sphere? Well, then good news! It's a suppository. A true inspiration for the children. Ah, computer dating. It's like pimping, but you rarely have to use the phrase "upside your head." " /] 

Затем в коде

 function shortcode_handler($atts, $content, $tag) { if(isset($atts['child'])) $output = shortcode_handler(array('count'=>$atts['child']), $atts[$atts['child'].'_text']) // Do something else with the output } 

Я знаю, что это не выглядит хорошо, но, возможно, вы можете что-то сделать в контексте своего приложения.

Я написал небольшую функцию, которая позволит использовать короткие коды. Он должен отлично работать для вашей проблемы. Это было очень полезно для меня.

Откройте файл «wp-includes / shortcodes.php» и измените функцию do_shortcode () (в строке 201) на следующую

 function do_shortcode($content) { global $shortcode_tags; if (empty($shortcode_tags) || !is_array($shortcode_tags)) return $content; $content = enable_recursive_shortcodes($content); $pattern = get_shortcode_regex(); return preg_replace_callback( "/$pattern/s", 'do_shortcode_tag', $content ); } 

Все, что было изменено, это добавление * $ content = enable_recursive_shortcodes ($ content); *

Эта функция проходит через переданный ей контент $ content и добавляет суффикс для коротких имен коротких кодов внутри себя. Затем обрабатываются только внешние короткие коды, и когда их содержимое обрабатывается, суффикс удаляется, что позволяет обрабатывать их. Нет предела тому, сколько уровней он может пройти. (пример: [box] [box] [box] [box] Содержимое [/ box] [/ box] [/ box] [/ box])

Добавьте функцию выше функции do_shortcode ()

 /** * Add shortcode suffix enabling recursive shortchodes. * * This function goes inside the set of $recursive_tags and adds a suffix to * the shortcode name so it will allow a shortcode to call itself in its content * * @since 2.5 * @return string Content with recursive shortcodes modified out. */ function enable_recursive_shortcodes($content) { $recursive_tags = array( 'column', 'div', 'span', 'table' ); // define recursive shortcodes, these must have closing tags $suffix = '__recursive'; // suffix is added to the tag of recursive shortcodes $content = str_replace( $suffix, '', $content ); // remove old suffix on shortcodes to start process over foreach( $recursive_tags as $recursive_tag ) { $open_tag = '[' . $recursive_tag . ' '; $close_tag = '[/'. $recursive_tag . ']'; $open_tags = 0; $open_pos = stripos( $content, $open_tag ); // find first opening tag $offset = $open_pos + strlen( $open_tag ); // set offset for first closing tag while( $open_pos !== false ) { $close_pos = stripos( $content, $close_tag, $offset ); // find first closing tag if(++$open_tags > 1) { // if we are inside an open tag // modify open tag from original shortcode name $content = substr( $content, 0, $open_pos ) . '[' .$recursive_tag . $suffix . ' ' . substr( $content, $offset ); // modify closing tag from original shortcode name $content = substr( $content, 0, $close_pos + strlen($suffix) ) . '[/'.$recursive_tag.'__recursive]' . substr( $content, $close_pos + strlen( $close_tag ) + strlen($suffix) ); $open_tags--; } $open_pos = stripos( $content, $open_tag, $offset ); // find next opening tag if( $close_pos < $open_pos ) $open_tags--; // if closing tag comes before next opening tag, lower open tag count $offset = $open_pos + strlen($open_tag); // set new offset for next open tag search } } return $content; } 

Обязательно обновите переменную $ recursive_tags, как вам нужно. Только те теги будут проверяться для детей с одним именем. Эти теги должны иметь закрывающие теги [column] [/ column], потому что [column /] не будет работать. Они также должны иметь пробел после имени короткого кода в открывающем теге и без пробелов в закрывающем теге из-за того, как функция просматривает теги. Если кто-нибудь обновит код, чтобы работать с кодами [column] или [column /] style, пожалуйста, поделитесь.

Самое простое – хотя, может быть, и не самое лучшее – решение, которое я нашел для этого, – добавить тег несколько раз под небольшими вариациями. Например, в случае вопросника это может быть:

 function render_column( $atts, $content ) { // etc. return apply_filters( 'the_content', $content ); } add_shortcode( 'column', 'render_column' ); add_shortcode( 'column-level-2', 'render_column' ); add_shortcode( 'column-level-3', 'render_column' ); 

Для этого требуется небольшая дополнительная документация, и некоторые пользователи могут не сразу ее понять, но я чувствую, что она немного интуитивна, чем попросить пользователей поместить содержимое короткого кода в атрибут. И, конечно же, это решение представляет собой отдельную проблему обработки кавычек в атрибуте shortcode.