Часто на сайтах возникает необходимость вставлять в тексты страниц динамичные информационные блоки – баннеры, телефоны и т.д. Как правило, содержание этих блоков часто изменяется что существенно усложняет работу контент менеджера.
Упростить эту задачу помогут шорткоды (shortcode). Смысл их в том что в HTML-коде страницы вместо нужного контента вставляется символьный код, например [[phone]]
, а при выводе на фронте сайта он заменяется на нужную информацию.
Двойные квадратные скобки используются для того чтобы исключить ложную замену.
Простой пример замены шоркодов на контент:
$text = '
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
[[phone]]
<p>Sed porta justo sed nibh elementum condimentum.</p>
[[address]]
';
$text = str_ireplace('[[phone]]', '+7 (495) 000-00-00', $text);
$text = str_ireplace('[[address]]', 'г.Москва, Тверская д.9', $text);
echo $text;
Результат:
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
+7 (495) 000-00-00
<p>Sed porta justo sed nibh elementum condimentum.</p>
г.Москва, Тверская д.9
Шорткоды с контентом из массива
Данный функционал можно реализовать на регулярных выражениях, функцией preg_match_all()
.
$text = '
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
[[phone]]
<p>Sed porta justo sed nibh elementum condimentum.</p>
[[address]]
';
// Массив значений
$info = array(
'phone' => '+7 (495) 000-00-00',
'address' => 'г.Москва, Тверская д.9',
);
// Поиск и замена
preg_match_all("|\[\[(.*)\]\]|U", $text, $matches);
if (!empty($matches[1])) {
foreach ($matches[1] as $row) {
$replase = (empty($info[$row])) ? '' : $info[$row];
$text = str_ireplace('[[' . $row . ']]', $replase, $text);
}
}
echo $text;
Результат:
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
+7 (495) 000-00-00
<p>Sed porta justo sed nibh elementum condimentum.</p>
г.Москва, Тверская д.9
В следующим примере используются шорткод вида [[blocks.XX]]
, где XX указывает ID нужной записи в таблице `blocks`
.
$text = '
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
[[blocks.1]]
<p>Sed porta justo sed nibh elementum condimentum.</p>
[[blocks.2]]
';
// Подключение к БД
$dbh = new PDO('mysql:dbname=db_name;host=localhost', 'ЛОГИН', 'ПАРОЛЬ');
// Поиск и замена
preg_match_all("|\[\[blocks\.(.*)\]\]|U", $text, $matches);
if (!empty($matches[1])) {
foreach ($matches[1] as $row) {
$sth = $dbh->prepare("SELECT `text` FROM `blocks` WHERE `id` = ?");
$sth->execute(array($row));
$item = $sth->fetch(PDO::FETCH_ASSOC);
$replase = (empty($item['text'])) ? '' : $item['text'];
$text = str_ireplace('[[blocks.' . $row . ']]', $replase, $text);
}
}
echo $text;
Как вариант замену кодов можно производить в callback-функции буферизации вывода ob_start()
:
<?php
// Подключение к БД
$dbh = new PDO('mysql:dbname=db_name;host=localhost', 'ЛОГИН', 'ПАРОЛЬ');
function callback($buffer)
{
preg_match_all("|\[\[blocks\.(.*)\]\]|U", $buffer, $matches);
if (!empty($matches[1])) {
foreach ($matches[1] as $row) {
$sth = $dbh->prepare("SELECT `text` FROM `blocks` WHERE `id` = ?");
$sth->execute(array($row));
$item = $sth->fetch(PDO::FETCH_ASSOC);
$replase = (empty($item['text'])) ? '' : $item['text'];
$buffer = str_ireplace('[[blocks.' . $row . ']]', $replase, $buffer);
}
}
return $buffer;
}
ob_start('callback');
?>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
[[blocks.1]]
<p>Sed porta justo sed nibh elementum condimentum.</p>
[[blocks.2]]
Второй вариант со скидыванием буфера в переменную с помощью функции ob_get_contents()
:
<?php
// Подключение к БД
$dbh = new PDO('mysql:dbname=db_name;host=localhost', 'ЛОГИН', 'ПАРОЛЬ');
ob_start();
?>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
[[blocks.1]]
<p>Sed porta justo sed nibh elementum condimentum.</p>
[[blocks.2]]
<?php
$buffer = ob_get_contents();
ob_end_clean();
preg_match_all("|\[\[blocks\.(.*)\]\]|U", $buffer, $matches);
if (!empty($matches[1])) {
foreach ($matches[1] as $row) {
$sth = $dbh->prepare("SELECT `text` FROM `blocks` WHERE `id` = ?");
$sth->execute(array($row));
$item = $sth->fetch(PDO::FETCH_ASSOC);
$replase = (empty($item['text'])) ? '' : $item['text'];
$buffer = str_ireplace('[[blocks.' . $row . ']]', $replase, $buffer);
}
}
echo $buffer;