Проблема с выводом шорткода перед контентом в WordPress
Возможный дубликат:
проблема с шорткодом
Проблема с работой шорткодов.
Для тех, кто хочет воспроизвести проблему, вот пошаговая инструкция.
1) Установите чистую версию WordPress (3.4.2).
2) В файле twentyeleven/functions.php добавьте следующий код:
function test() {
echo '-TEST-';
}
add_shortcode('testshortcode', 'test');
3) Отредактируйте пост "Hello world", чтобы он содержал:
Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!
[testshortcode]
foobar
4) Сохраните и посмотрите результат. У меня получается следующее:
-TEST-
Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!
foobar
Хотя должно быть так:
Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!
-TEST-
foobar
Что здесь происходит?

Обратные вызовы шорткодов должны возвращать значение, а не выводить его. Поэтому используйте следующий подход:
function test() {
return '-TEST-';
}
add_shortcode( 'testshortcode', 'test' );
Подробнее: http://codex.wordpress.org/Shortcode_API
Если вам необходимо использовать echo, можно также сделать так (полезно, если много разметки и сложно работать со строками):
function test() {
ob_start();
echo '-TEST-';
return ob_get_contents();
}
add_shortcode( 'testshortcode', 'test' );

Это интересно, на чистой установке это работает, но не работает в плагине, который делает то же самое. Там использовался echo, и он не срабатывал, как в моем примере, но когда я заменил его на return, всё равно не работает. Вот плагин http://wordpress.org/extend/plugins/wordpress-media-tags/

Я скачал плагин и проверил: если заменить там echo на return, контент вернется в вызывающую функцию, а не в WordPress.

Я только что это понял и собирался написать: если добавить еще один return в функцию, которую вызывает колбэк, и заменить echo, то всё работает. Спасибо.

У меня это выводило контент дважды (один раз перед содержимым, второй — там, где я хотел). Я решил это так:
function test()
{
ob_start();
echo '-TEST-';
$ReturnString = ob_get_contents();
ob_end_clean();
return $ReturnString;
}
