current_shortcode () - определить используемый в настоящее время шорткод

11

В классе плагинов я хочу предоставить простые поля для общедоступных данных: электронная почта, номер телефона, Twitter и т. Д. Список можно расширить.

Смотрите плагин Public Contact Data на GitHub для деталей.

Для простоты использования я также хочу предложить короткие коды, которые легко набирать:

  • [public_email]
  • [public_phone]
  • [public_something]

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

foreach ( $this->fields as $key => $value )
{
    add_shortcode( 'public_' . $key, array( $this, 'shortcode_handler' ) );
}

Теперь shortcode_handler()нужно знать, какой шорткод был вызван. Мой вопрос: как мне это сделать?

Мой нынешний способ это еще одна функция:

protected function current_shortcode()
{
    $backtrace = debug_backtrace( DEBUG_BACKTRACE_IGNORE_ARGS );
    return $backtrace[3]['args'][0][2];
}

Это ... работает для the_content(). Но это не элегантно и не надёжно.
Я прочитал wp-includes/shortcodes.php, но я не вижу сейчас, как это сделать лучше.

Фуксия
источник
1
У меня сейчас все любопытно. Я посмотрю на это в ближайшее время. Я знаю, что shortcodes.php - это просто набор функций, если бы он был написан правильно с использованием ООП, он, несомненно, имел бы переменную класса current_shortcode и сделал бы все проще. Насколько мне известно, Wordpress хранит только все шорткоды и обратные вызовы в массиве. Интересно, есть ли способ заставить его хранить каждый шорткод в переменной по мере обработки и без взлома основных файлов?
Дуэйн Чаррингтон
@toscho Согласен, я думаю, что это действительно проблема, следует помнить о ремоделировании способов создания шорткодов (охватывающих больше ООП, таких как виджеты). Я хотел бы помочь в этом, а позже отправить это в качестве обновления в ядро.
Веборд
@brasofilo Правильно, я сделал это только сейчас.
fuxia

Ответы:

3

Это не проверено , но функция обратного вызова снабжена массивом аргументов, $argsкоторые дают (если таковые имеются) параметры, предоставляемые шорткодом. Нулевая запись иногда содержит название используемого шорткода (например public_email). Иногда я имею в виду ...

Нулевая запись массива атрибутов ($ atts [0]) будет содержать строку, которая соответствует регулярному выражению шорткода, но ТОЛЬКО если это отличается от имени обратного вызова, которое в противном случае появляется в качестве третьего аргумента функции обратного вызова.

(См. Кодекс ). Для ваших целей тогда $atts[0]будет содержаться либо public_emailи public_phoneт.д.

function shortcode_handler($atts,$content=NULL){
     if(!isset($atts[0]))
         return; //error?

     switch($atts[0]):
         case 'public_email':
              //deal with this case
              break;
         case 'public_phone':
              //deal with this case
              break;
         case 'public_something':
              //deal with this case
              break;
     endswitch;   
}
Стивен Харрис
источник
Ах, я помню, я столкнулся с чем-то подобным давным-давно. В моем случае это третий аргумент для обработчика шорткода. Первый $args, второй $contentи последний шорткод!
fuxia
В самом деле? Шорткод отличается от имени обратного вызова «shortcode_handler» ... Я бы подумал, что он был бы указан в $args. Но если это работает для вас ...: D.
Стивен Харрис
2

Основываясь на ответе Стивена Харриса, я заставил свой обработчик catch all принять третий аргумент, который является сокращенным именем:

/**
 * Handler for all shortcodes.
 *
 * @param  array  $args
 * @param  NULL   $content Not used.
 * @param  string $shortcode Name of the current shortcode.
 * @return string
 */
public function shortcode_handler(  $args = array (), $content = NULL, $shortcode = '' )
{
    $key = $this->current_shortcode_key( $shortcode );
    $args['print'] = FALSE;
    return $this->action_handler( $key, $args );
}

/**
 * Returns the currently used shortcode. Sometimes.
 *
 * @return string
 */
protected function current_shortcode_key( $shortcode )
{
    return substr( $shortcode, 7 );
}

Посмотрите это в действии в плагине, связанном в моем вопросе.

Фуксия
источник