http://wm-monitoring.ru/ ')) {alert('Спасибо за то что установили нашу кнопку! =)');} else {alert('Очень жаль! =(');}"> http://wm-monitoring.ru/

Как правильно интегрировать сниппеты Google в тему WordPress

Опубликовано: 01.09.2018

видео Как правильно интегрировать сниппеты Google в тему WordPress

Как добавить новые функции в functions.php WordPress - ShortCode API

Все мы знакомы с тем, как поисковик Google отображает результаты поиска: перед нами появляется страница с заголовком и небольшим сниппетом с текстом для каждого из результатов поискового запроса. При помощи рич-сниппетов () у нас есть возможность добавить полезные данные к результатам поиска, чтобы выделить конкретную позицию из остальных результатов поисковой выдачи и привлечь таким путем больше посетителей на сайт нашего проекта.



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


SEO оптимизация WordPress сайта для эффективного продвижения в Google и Яндекс

| Скачать исходники |

Введение в рич-сниппеты Google

Давайте для начала взглянем на пример того, как выглядит такой рич-сниппет:

Я выделил для вас те сниппеты с дополнительной информацией, которую поисковик Google "считывает" со страницы. Как вы сами можете увидеть, рич-сниппеты добавляют по-настоящему полезную информацию к результатам, которые выдает по запросу поисковый движок. В случае с кулинарными рецептами эта дополнительная информация включает фото, рейтинг рецепта, сумму калорий и общее время на приготовления конкретного блюда. Вся эта дополнительная информация дает пользователям куда лучшее представление о содержимом страницы, и повышается вероятность того, что пользователь кликнет по вашей ссылке и перейдет на ваш сайт.


Slack. Подробное руководство

Как включить рич-сниппеты?

Секрет использования рич-сниппетов кроется в структурированной семантической разметке, которая позволяет поисковику Google "понять" контент на странице. Поэтому основное, что вам надо будет сделать — это правильно провести разметку контента , чтобы описать конкретные типы информации на вашем вебсайте.

В данном практическом руководстве мы сосредоточимся на подготовке рич-сниппетов для сайта с кулинарными рецептами. Но в Google есть поддержка рич-сниппетов для целого ряда различных типов контента, а именно:

Обзоры Данные о людях Данные о продуктах и товарах Бизнесы и организации Информация о мероприятиях Данные о музыке

Для детальной информации о рич-сниппетах и поддерживаемых типах контента посетите страницу Google Help Center .

Когда речь заходит о разметке вашего контента, есть три основных типа разметки, из которых вам надо выбрать:

Микро-данные Микро-форматы RDFa

В этом руководстве мы интегрируем разметку микро-данных со свойствами schema.org , согласно требованиям документации по рич-сниппетам от Google. Стоит сказать, что словарь разметки schema.org распознается не только в поисковике от компании Google, но и в поисковых системах от Yahoo! и Microsoft .

Для детальной информации о примерах вставки кода на ваш сайт посетите Schema.org .

Шаг 1. Создаем настраиваемые типы постов (Custom Post Type)

Поскольку мы будем писать немало кода, давайте создадим отдельный файл под названием recipe-config.php , в котором будут перечислены все наши сниппеты, а сам этот файл включим при помощи PHP-функции include . Чтобы сделать это, откройте ваш файл functions.php в папке с текущей темой сайта и вставьте следующий код в конце файла:

include('recipe-config.php');

Теперь создадим новый файл под названием recipe-config.php . Весь дальнейший код будем включать в состав этого файла.

Начнем с того, что создадим новый настраиваемый тип постов под названием " Рецепты " (Recipe).

add_action( 'init', 'register_my_culinary_recipe' ); function register_my_culinary_recipe() { $labels = array( 'name' => _x( 'Recipes', 'culinary_recipes' ), 'singular_name' => _x( 'Recipe', 'culinary_recipes' ), 'add_new' => _x( 'Add New', 'culinary_recipes' ), 'add_new_item' => _x( 'Add New Recipe', 'culinary_recipes' ), 'edit_item' => _x( 'Edit Recipe', 'culinary_recipes' ), 'new_item' => _x( 'New Recipe', 'culinary_recipes' ), 'view_item' => _x( 'View Recipe', 'culinary_recipes' ), 'search_items' => _x( 'Search Recipes', 'culinary_recipes' ), 'not_found' => _x( 'No Recipes found', 'culinary_recipes' ), 'not_found_in_trash' => _x( 'No recipes found in Trash', 'culinary_recipes' ), 'parent_item_colon' => '', 'menu_name' => _x( 'Recipes', 'culinary_recipes' ) ); $args = array( 'labels' => $labels, 'public' => true, 'publicly_queryable' => true, 'show_ui' => true, 'show_in_menu' => true, 'show_in_nav_menus' => true, 'exclude_from_search' => false, 'hierarchical' => false, 'has_archive' => true, 'rewrite' => array('slug' => 'recipe') ); register_post_type( 'my_culinary_recipe', $args ); }

Теперь если вы перейдете в раздел администратора, там появится новая опция в меню под названием " Recipes ". Пока не добавляйте никаких рецептов, потому что нам сначала надо настроить мета-блоки .

Шаг 2. Добавляем настраиваемые мета-ячейки (Custom Meta Boxes)

Установка

Поскольку нам понадобятся всего несколько мета-блоков для различных типов рецептов, чтобы сохранять конкретные типы информации из рецептов, то я собираюсь для этой цели использовать бесплатную библиотеку Custom Meta Boxes and Fields for WordPress . Вы, само собой, можете использовать любой другой сторонний скрипт или создать мета-ячейки с нуля, если захотите.

На Wptuts+ есть отличное пошаговое руководство о том, как их создавать: Reusable Custom Meta Boxes

Сперва скачаем данную библиотеку с GitHub . Как предлагает автор, мы сохраним все файлы скрипта в папке ‘ lib/metabox ‘. так что начните с того, что создайте папку под названием ‘ lib ‘ в вашей теме или дочерней теме; затем добавьте папку ‘ metabox ‘ внутри папки ‘ lib ‘. Распакуйте и выгрузите все скачиваемые файлы в ‘ /wp-content/themes/my-theme/lib/metabox ‘.

И наконец, нам надо включить файл init.php . Обычно его включают в состав файла functions.php , но нам надо сделать эту процедуру внутри файла recipe-config.php , поскольку именно в этом новом файле будут хранится специфические функции, связанные с рецептами как типом контента на сайте.

function be_initialize_cmb_meta_boxes() { if ( !class_exists( 'cmb_Meta_Box' ) ) { require_once( 'lib/metabox/init.php' ); } } add_action( 'init', 'be_initialize_cmb_meta_boxes', 9999 );

Задаем значения мета-ячеек (Meta Boxes)

Чтобы получить возможность работы с Google Rich Snippets , нам нет нужды перечислять все свойства, включенные в спецификацию, хотя у каждого типа контента есть свой набор минимальных требований к информации для сниппетов. В данном практическом руководстве мы собираемся объединить следующие свойства :

name recipeCategory image description ingredients instructions recipeYield prepTime cookTime totalTime datePublished author

Учтите, что мы не будем создавать отдельные мета-блоки для всех свойств. К примеру,  totalTime  будет рассчитываться, исходя из значений prepTime и cookTime .

Итак, давайте добавим несколько мета-блоков:

$prefix = 'mcr_'; // Prefix for all fields function mcr_create_metaboxes( $meta_boxes ) { global $prefix; $meta_boxes[] = array( 'id' => 'recipe-data', 'title' => 'Culinary Recipe', 'pages' => array('my_culinary_recipe'), 'context' => 'normal', 'priority' => 'high', 'show_names' => true, 'fields' => array( //TITLE - TEXT array( 'name' => __( 'Recipe Title', 'culinary_recipes' ), 'id' => $prefix . 'name', 'type' => 'text', ), //RECIPE TYPE - TEXT array( 'name' => __( 'Recipe Type', 'culinary_recipes' ), 'desc' => __( 'The type of dish: for example, appetizer, entree, dessert, etc.', 'culinary_recipes' ), 'id' => $prefix . 'type', 'type' => 'text_medium', ), // IMAGE UPLOAD array( 'name' => 'Recipe Image', 'desc' => 'Image of the dish being prepared.', 'id' => $prefix . 'image', 'type' => 'file', 'save_id' => false, // save ID using true 'allow' => array('url', 'attachment') // limit to just attachments with array( 'attachment' ) ), //SUMMARY - TEXT array( 'name' => __( 'Summary', 'culinary_recipes' ), 'desc' => __( 'A short summary describing the dish.', 'culinary_recipes' ), 'id' => $prefix . 'summary', 'type' => 'text', ), //INGREDIENTS - TEXTAREA array( 'name' => __( 'Ingredients', 'culinary_recipes' ), 'desc' => __( 'Put each ingredient in seaprate line.', 'culinary_recipes' ), 'id' => $prefix . 'ingredients', 'type' => 'textarea', ), //DIRECTIONS - TEXTAREA array( 'name' => __( 'Instructions', 'culinary_recipes' ), 'desc' => __( 'Put each instruction in seaprate line.', 'culinary_recipes' ), 'id' => $prefix . 'instructions', 'type' => 'textarea', ), //YIELD - TEXT array( 'name' => __( 'Yield', 'culinary_recipes' ), 'desc' => __( 'Enter the number of servings or number of people served', 'culinary_recipes' ), 'id' => $prefix . 'yield', 'type' => 'text_medium', ), //PREP TIME - TITLE array( 'name' => __( 'Prep time', 'culinary_recipes' ), 'desc' => __( 'How long does it take to prep?', 'culinary_recipes' ), 'type' => 'title', 'id' => $prefix . 'prep_title' ), //PREP TIME HOURS - NUMBER array( 'name' => __( 'Hours', 'culinary_recipes' ), 'id' => $prefix . 'prep_time_hours', 'type' => 'number', 'std' => '0', ), //PREP TIME MINUTES- NUMBER array( 'name' => __( 'Minutes', 'culinary_recipes' ), 'id' => $prefix . 'prep_time_minutes', 'type' => 'number', 'std' => '0', ), //COOK TIME - TITLE array( 'name' => __( 'Cooking time', 'culinary_recipes' ), 'desc' => __( 'Total time of cooking, baking etc.', 'culinary_recipes' ), 'type' => 'title', 'id' => $prefix . 'coking_title' ), //COOKING TIME - TEXT array( 'name' => __( 'Hours', 'culinary_recipes' ), 'id' => $prefix . 'cook_time_hours', 'type' => 'number', 'std' => '0', ), //COOKING TIME - TEXT array( 'name' => __( 'Minutes', 'culinary_recipes' ), 'id' => $prefix . 'cook_time_minutes', 'type' => 'number', 'std' => '0', ) ) ); return $meta_boxes; } add_filter( 'cmb_meta_boxes' , 'mcr_create_metaboxes' );

При помощи данного фрагмента кода мы создали мета-блок под названием " Culinary Recipe ", который будет отображать только экран для редактирования типа постов и текста с рецептами.

Сами определения полей хранятся в массиве в свойствах ‘ fields ‘. Давайте посмотрим подробнее:

array( 'name' => __('Summary', 'culinary_recipes'), 'desc' => __('A short summary describing the dish.', 'culinary_recipes'), 'id' => $prefix .'summary', 'type' => 'text', ),

Добавить новое поле здесь так же легко, как скопировать один из элементов массива (представленных выше) и изменить значения для полей ‘ name ‘, ‘ id ‘, ‘ desc ‘ и ‘ type ‘. Библиотеки Custom Metaboxes и Fields предлагают нам  набор заранее заданных типов полей , a также удобный метод для определения собственного типа полей.

Для того, чтобы отображать отдельно значения часов и минут для времени готовки и подготовки блюда, я ввел собственное определение поля под названием ‘ number ‘. Я использовал один из типов ввода для HTML5: " number " — и создал простую функцию валидации, выбирая переменные значения из набора значений, предоставленных пользователем.

add_action( 'cmb_render_number', 'rrh_cmb_render_number', 10, 2 ); function rrh_cmb_render_number( $field, $meta ) { echo '<input type="number" min="0" max="60" class="cmb_text_inline" name="', $field['id'], '" id="', $field['id'], '" value="', '' !== $meta ? $meta : $field['std'], '" />','<p class="cmb_metabox_description">', $field['desc'], '</p>'; } add_filter( 'cmb_validate_number', 'rrh_cmb_validate_number' ); function rrh_cmb_validate_number( $new ) { return (int)$new; }

Шаг 3. Отображаем выбранный контент

Теперь мы наконец-то готовы к тому, чтобы написать разметку контента. Мы могли бы создать отдельный файл шаблона для нашего настраиваемого типа постов и поместить разметку прямо в этот шаблон. Но вместо этого мы поместим всю разметку внутрь функции и добавим ее к контенту поста с помощью фильтра the_content() .

Это важный момент, поскольку есть много плагинов, которые добавляют тот или иной вид контента, например кнопки для социальных сетей, в конец поста. Таким способом добавления мы будем уверены, что весь вывод данных в плагине будет отображаться под текстом самого рецепта.

function mcr_display_recipe($content) { global $post; $recipe = ''; if ( is_singular( 'my_culinary_recipe' ) ) { $recipe .= '<div class="recipe">'; $recipe .= '<div itemscope itemtype="http://schema.org/Recipe" >'; $recipe .= '<h2 itemprop="name">'. get_post_meta($post->ID,'mcr_name',true) .'</h2>'; $recipe .= '<img class="alignright" itemprop="image" src="'. get_post_meta($post->ID,'mcr_image',true) .'" />'; $recipe .= '<span class="mcr_meta"><b>Recipe type:</b> <time itemprop="recipeCategory">'. get_post_meta($post->ID,'mcr_type',true) .'</time></span>'; $recipe .= '<span class="mcr_meta"><b>Yield:</b> <span itemprop="recipeYield">'. get_post_meta($post->ID,'mcr_yield',true) .'</span></span>'; $recipe .= '<span class="mcr_meta"><b>Prep time:</b> <time content="'. mcr_time('prep','iso') .'" itemprop="prepTime">'. mcr_time('prep') .'</time></span>'; $recipe .= '<span class="mcr_meta"><b>Cook time:</b> <time content="'. mcr_time('cook','iso') .'" itemprop="cookTime">'. mcr_time('cook') .'</time></span>'; $recipe .= '<span class="mcr_meta"><b>Total time:</b> <time content="'. mcr_total_time('iso') .'" itemprop="totalTime">'. mcr_total_time() .'</time></span>'; $recipe .= '</br>'; $recipe .= '<hr />'; $recipe .= '<span itemprop="description">'. get_post_meta($post->ID,'mcr_summary',true) .'</span><br />'; $recipe .= '<h3>Ingredients:</h3> '. mcr_list_items('ingredients'); $recipe .= '<h3>Directions:</h3> '. mcr_list_items('instructions'); $recipe .= '<span class="mcr_meta">Published on <time itemprop="datePublished" content="'. get_the_date('Y-m-d') .'">'. get_the_date('F j, Y') .'</time></span>'; $recipe .= '<span class="mcr_meta">by <span itemprop="author">'. get_the_author() .'</span></span>'; $recipe .= '</div>'; $recipe .= '</div>'; } return $content . $recipe; } add_filter('the_content', 'mcr_display_recipe', 1);

Давайте разберемся с кодом. Первым делом мы "вытягиваем" общий объект $post , что дает нам доступ к различной полезной информации о посте, который отображается в данный момент.

Затем мы используем условный тег is_singular() для того, чтобы проверить, является ли отдельный пост типа ‘ my_culinary_recipe ‘ тем, который мы видим в настоящий момент. Это происходит потому, что мы не создавали отдельный шаблон для нашего нового типа постов (для рецептов), а потому WordPress использует более общий шаблон single.php (либо же index.php , если нет single.php ) для отображения нашего рецепта. Используя критерий утверждения if , мы можем убедиться, что разметка рецепта не будет отображаться в остальных, обычных постах.

И наконец, мы получаем данные рецепта при помощи функции get_post_meta() и помещаем ее в разметку, которая структурирована согласно формату микро-данных.

Вспомогательные функции

Вы наверняка заметили, что я использовал несколько дополнительных функций: mcr_time() , mcr__total_time() и mcr_list_items() , — чтобы получить и подготовить данные к отображению. Давайте разберем и этот момент.

Свойства, связанные со временем приготовления блюда ( prepTime , cookTime и totalTime ), задаются в формате ISO 86 01 . Чтобы учесть этот момент, все наши функции времени будут принимать формат как параметр, и вывод также я оформил соответствующим образом.

function mcr_time($type = 'prep', $format = null) { global $post; $hours = get_post_meta($post->ID,'mcr_'.$type.'_time_hours',true); $minutes = get_post_meta($post->ID,'mcr_'.$type.'_time_minutes',true); $time = ''; if ($format == 'iso') { if ($hours > 0) { $time = 'PT'.$hours.'H'; if($minutes > 0) { $time .= $minutes.'M'; } } else { $time = 'PT'.$minutes.'M'; } } else { if ($hours > 0) { if ($hours == 1) { $time = $hours.' hour '; } else { $time = $hours.' hrs '; } if ($minutes > 0) { $time .= $minutes.' mins'; } } else { $time = $minutes.' mins'; } } return $time; }

Функция mcr_time() подготавливает вывод для времени приготовления и готовности блюда, и принимает 2 параметра:

function mcr_total_time($format = null) { global $post; $prep_hours = get_post_meta($post->ID,'mcr_prep_time_hours',true); $prep_minutes = get_post_meta($post->ID,'mcr_prep_time_minutes',true); $cook_hours = get_post_meta($post->ID,'mcr_cook_time_hours',true); $cook_minutes = get_post_meta($post->ID,'mcr_cook_time_minutes',true); $total_minutes = ($prep_hours + $cook_hours)*60 + $prep_minutes + $cook_minutes; $hours = 0; $minutes = 0; if ($total_minutes >= 60) { $hours = floor($total_minutes / 60); $minutes = $total_minutes - ($hours * 60); } else { $minutes = $total_minutes; } $total_time = ''; if ($format == 'iso') { if ($hours > 0 ) { $total_time = 'PT'.$hours.'H'; if ($minutes > 0) { $total_time .= $minutes.'M'; } } else { $total_time = 'PT'.$minutes.'M'; } } else { if ($hours > 0 ) { if ($hours == 1) { $total_time = $hours.' hour '; } else { $total_time = $hours.' hrs '; } if ($minutes > 0) { $total_time .= $minutes.' mins'; } } else { $total_time = $minutes.' mins'; } } return $total_time; }

Функция mcr_total_time() подсчитывает и выводит значение общего времени для конкретного рецепта. Она принимает только один параметр: $format , аналогичный параметру $format в функции mcr_time() .

И последняя вспомогательная функция отображает перечень компонентов или инструкция для рецепта, согласно параметру $type :

function mcr_list_items($type = 'ingredients') { global $post; if (get_post_meta($post->ID, 'mcr_'. $type, true)) { $get_items = get_post_meta($post->ID, 'mcr_'. $type, true); $items = explode("r", $get_items); $list = ''; } else { return; } if ($type=='ingredients') { $list .= '<ul>'; foreach ($items as $item) { $list .= '<li><span itemprop="ingredients">' . trim($item) . '</span></li>'; } $list .= '</ul>'; } elseif ($type=='instructions') { $list .= '<ol itemprop="recipeInstructions">'; foreach ($items as $item) { $list .= '<li>' . trim($item) . '</li>'; } $list .= '</ol>'; } else { $list .= 'Invalid list type.'; } return $list; }

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

Вот и все! Единственное, что осталось, — это проверка корректности разметки с помощью инструмента тестирования рич-сниппетов от Google.

Вот как выглядит блок рич-сниппета в режиме предварительного просмотра, сгенерированный на базе нашей HTML-разметки:

Вы можете протестировать свою разметку путем подстановки URL или кода сниппета в инструмент тестирования.

Как только вы добавите разметку рич-сниппетов, подождите какое-то время, чтобы Google обнаружил внесенные вами измнения. Когда Google обнаружит новую разметку, поисковик начнет показывать рич-сниппеты для вашего сайта в поисковых результатах. Вы также можете подать заявку через форму , чтобы оповестить Google о появлении рич-сниппетов на вашем сайте, но сперва стоит дать немного времени поисковику.

Заключение

В этом пошаговом руководстве я показал вам, как интегрировать формат микро-данных согласно словарю от schema.org для отображения кулинарных рецептов. Данный пример может послужить вам практическим шаблоном, который вы можете использовать в качестве "дорожной карты" при настройке рич-сниппетов для других типов контента. Использовали ли вы Google Rich Snippets для каких-либо типов контента в ваших проектах? Расскажите нам об этом в комментариях.

Источник:  
Карта
rss