Как сделать микроразметку schema.org для рецептов при помощи функции

Опубликовано ,

Сразу оговорюсь — плагин Schema Creator by Raven я попробовала, но мне не особо понравилось, хоть и перевела его под собственные нужды. Поэтому взяла за основу только идею, но об этом позже.

Сначала хотела уместить все в одном файле, но текст получился уж больно объемным. Поэтому разделен на 2 части + введение.

Содержание:

Часть 1. Общая информация

Микроразметка schema.org: коротко о главном

Часть 2. Function

  1. Введение
  2. Микроразметка при помощи функций
    • Плюсы и минусы метода;
    • Разметка этапов приготовления;
    • Разметка ингредиентов;
    • Разметка изображений.

Часть 3. Custom fields

На истину в последней инстанции не претендую и готова выслушать все предложения =)

А так у нас выглядит плагин Schema Creator by Raven — в принципе, тоже неплохой вариант, но мне не захотелось его использовать ибо больная голова ногам покою не дает:

schema-creator-raven

За основу своей разметки я беру пример, приводимый в разделе «Помощь» Яндекс.Вебмастера. вот он:

html-microrazmetka schema.org

Для каждого рецепта у нас обязательные всего три поля: name (название), ingredients (ингредиенты) и recipeInstructions (инструкция по приготовлению), — их мы и разметим при помощи функции. Остальные пункты при желании можно задать при помощи произвольных полей. О том, как это сделать я расскажу в следующий раз.

Таким образом, каркас нашего рецепта будет выглядеть следующим образом:

<div itemscope itemtype="http://schema.org/Recipe"> /*задаем словарь*/
  <h1 itemprop="name">Заголовок</h1>                /*название рецепта*/
    <i itemprop="author">Автор</i>                  /*автор рецепта*/
       <h2>Ингредиенты:</h2>                        /*ингредиенты - маркированный список*/
          <ul>
            <li itemprop="ingredients">...</li>
            ....
          </ul>
       <h2>Приготовление:</h2>                      /*этапы - нумерованный список*/
          <ol itemprop="recipeInstructions">
            <li>текст этапа
               <img itemprop="image" src=" "/> 
            </li>
            .....
          </ol>
</div>

Если интересно, вот список всех поддерживаемых полей (мне достаточно необходимого минимума):

Поддерживаемые поля для разметки рецепта schema.org

Как вы понимаете, вручную вбивать это довольно нудно. Что ж, будем автоматизировать процесс.

Для работы нам понадобятся:

  • Размеченный как статья (Article) шаблон одиночной записи single.php;
  • Раздел «Рецепты» на блоге;
  • Внимательность

Микроразметка страницы с рецептом

Плюсы:

  • Полная автоматизация, никаких лишних действий
  • Минимальные исправления в шаблоне

Минус:

  • Необходимость придерживаться определенного шаблона записи
Примечание: нижеследующие функции привязаны к определенной структуре документа. Следует ее соблюдать, либо заменить соответствующие теги

Разметка для названия и автора (если брать автор статьи — это автор рецепта) рецепта у нас такая же, как для Article, так что тут ничего менять не надо:

/*автор*/
<i itemprop="author"><?php the_author(); ?></i>

/*заголовок*/
<h1 itemprop="name"><?php the_title(); ?></h1>

Для внедрения микроразметки schema.org в шаблон записи я буду использовать функцию str_replace, заменяющую заданное выражение на новое. Однако, как мы видим из представленного выше шаблона разметки, тег <li> встречается у нас как в маркированном, так и в нумерованном списках, при этом в списке ингредиентов атрибут надо добавлять в каждую строчку. Так что, одной функцией в этот раз мы не отделаемся.

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

Для этого зайдем в админке «Записи/Рубрики» и выберем нужную категорию. У меня это, соответственно, «Рецептики». Для быстрого определения ID я добавила в файл функций function.php специальный сниппет, взятый с wp-kama, так что узнать номер рубрики не составляет труда:

id категории

Если же у вас не добавлена такая функция, заходим на страничку рубрики, щелкаем по адресу и смотрим айди:

id категории по адресу

Напоминаю. Не забывайте делать резервные копии при редактировании файлов шаблона. Лучше всего работать через FTP-клиент

1. Обозначим этапы приготовления

Что ж, начинаем писать первую функцию:

//микроразметка для этапов приготовления
function replace_recipe($recipe){
        $replace = array(
                // 'что заменяем' => 'на что заменяем'
                '<ol'=> '<ol itemprop="recipeInstructions"',
	); 
if(in_category(13)) {                      //задаем категорию
$recipe = str_replace(array_keys($replace), $replace, $recipe); //производим замену
}      
 return $recipe;                             //возвращаем значение функции
}
add_filter('the_content', 'replace_recipe');

Здесь мы задаем массив $replace, в котором в качестве ключа (array_keys($replace)) указываем, что требуется заменить, а в качестве значения — на что. При помощи функции замены str_replace заменяем существующие выражения на новые.

В данном примере массив состоит из одной строки, я оставила это так на случай, если придется вносить еще какие-то изменения в разметку рецепта.

Смотрим результат валидаторе Яндекса:

article-val

Как вы видите, у нас осталась микроразметка статьи — Article, следует ее заменить на Recipe. Поэтому открываем файл single.php и ищем блок, в котором задается тип шаблона. У меня он выглядит так:

<div itemscope itemtype="http://schema.org/Article" class="main_content">

Заменяем ее на следующее (не забываем добавить свой ID):

<?php if (in_category(13)) { ?>  /*для категории "Рецепты" - тип рецепты*/
    <div itemscope itemtype="http://schema.org/Recipe" class="main_content">
<? } else { ?>                   /*для остальных - статья*/
    <div itemscope itemtype="http://schema.org/Article" class="main_content">
<? } ?>

Проверяем в валидаторе:

recipe-val

Как видите, у нас осталось еще два лишних атрибута. Заменяем их аналогично:

/*атрибут для текста статьи*/
<?php if (in_category(13)) { ?>
   <?php the_content(); ?>
<? } else { ?>
   <div itemprop="articleBody"><?php the_content(); ?></div>
<? } ?>

/*атрибут для рубрики*/
<?php if (in_category(13)) { ?>
   <?php the_category(', ') ?>
<? } else { ?>
   <span itemprop="articleSection"><?php the_category(', ') ?></span>
<? } ?>

И снова проверяем:

instructions-val

Отлично, теперь переходим к следующему этапу.

2. Добавляем атрибуты к ингредиентам

val-recipe-ingredients

Теперь задание посложнее — следует добавить атрибут только к <li>, находящимся внутри маркированного списка <ul>

//разметка ингредиентов
function ingredients($ingr){ 
if(in_category(13)) {            //задаем категорию
$ingr = Preg_Replace_Callback(
    '!<ul>(.*?)</ul>!si',      //регулярное выражение для тегов и их содержимого
    Create_Function(
        '$matches',
        'Return Str_Replace("<li>", "<li itemprop=\"ingredients\">", $matches[0]);'   //заменяем
    ),
	$ingr
);
}     
 return $ingr;      
}
add_filter('the_content', 'ingredients');

В этот раз мы используем preg_replace_callback, которая осуществляет поиск по регулярному выражению и замену. От preg_replace данная функция отличается использованием дополнительной функции обратного вызова. В данном случае это create_function. Таким образом, мы ищем в тексте теги <ul>…</ul> и добавляем атрибут в каждый из <li> внутри.

Обратите внимание на «<li itemprop=\»ingredients\»>» — кавычки в атрибуте приходится экранировать.

Затем возвращаем результат.

Надеюсь, все понятно…

Проверяем:

ingredients-val

3. Заменяем изображения

Этот пункт аналогичен первому. Я вынесла его отдельно по следующей причине: атрибут «image» актуален не только в списке рецептов, но и в разметке всего блога, так что я не вижу смысла ограничивать его работу одной категорией. Соответственно, пишем общее правило:

//микроразметка для изображений
function schema_image($img){     
    $img = str_replace('<img','<img itemprop="image"', $img);    
    return $img;      
}
add_filter('the_content', 'schema_image');

Ну и проверка в валидаторе:

image-val

 

Вот и все =) Добавлять все три функции следует в файл functions.php перед закрывающим тегом ?>

Совет напоследок: при написании рецепта работайте в html-редакторе. Визуальный добавляет слишком много лишних тегов

Если что не получается или есть какие-то предложения — обязательно говорите.

Отправить ответ

38 Комментарий на "Как сделать микроразметку schema.org для рецептов при помощи функции"

avatar
  Subscribe  
newest oldest most voted
Notify of
Антонина
Гость

Добрый день, Анастасия! Хочу по вашей статье сделать микроразметку, но не поняла с какими файлами работаем. Открыть существующий single.php или (Размеченный как статья (Article) шаблон одиночной записи single.php;)создаем новый? Куда вставлять? Как это все должно выглядеть поэтапно? Как потом работать с рецептами? Вопросов очень много. Можно поподробней расписать для новичков? Спасибо.

Артем
Гость

Приветствую! Интересные решения, взял на заметку. Правда я больше предпочитаю полями размечать, хотя на действующих сайтах умрешь конечно.
Такой вопрос, как размечать главную для рецептов под Яндекс. Яша в своем репертуаре, обязательных тег у него — ингредиенты, а вот как их на главной не заметно вывести уже бошку сломал…. Ведь ингредиентов может быть много…

Тоха
Гость

Анастасия помогите мне настроит для блога разметку. ОШИБКА: префикс article неизвестен валидатору, укажите его явно атрибутом prefix

http://secret-recipe.ru/vipechka/pechene-s-tvorogom-k-chayu.html

В долгу не останусь $

Артем
Гость

Кому интересно, я решил как убрать данную ошибку https://www.youtube.com/watch?v=TJV4JOPul1E

Артур
Гость

Спасибо! Очень полезная статья.

Елена Прекрасная
Гость

Привет, Настя! Классная разметка для рецептов, я себе уже тоже такую захотела для рубрики Кулинария)

Света
Гость

Подскажите Анастасия. Если добавить все это, то надо будет все опуликованные рецепты на сайте удалять и добавлять снова, или эта микроразметка итак будет загружается из function.php с уже опубликованными рецептами? И ещё вопрос, если у меня несколько категорий, где рецепты, то id каждой категории надо через запятую приписывать в (in_category(13)) или как?

Михаил
Гость

Ура, всё получилось! Спасибо вам Анастасия! Очень полезная статья.

Людмила
Гость

Нужно ли сейчас прописывать что-то кроме itemprop=»image»‘ для картинок?

Например конструкция вида

<pre class="prettyprint lang-html data-start-line="1" data-visibility="visible"<img itemprop=»url» src=»адрес_изображения» alt=»****» width=»ширина» height=»высота»/>
<meta itemprop=»width» content=»ширина»>
<meta itemprop=»height» content=»высота»> </div>