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

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

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

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

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

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

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

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

Секрет использования рич-сниппетов кроется в структурированной семантической разметке, которая позволяет поисковику 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». Пока не добавляйте никаких рецептов, потому что нам сначала надо настроить мета-блоки.

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

Шаг 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», который будет отображать только экран для редактирования типа постов и текста с рецептами.

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

Сами определения полей хранятся в массиве в свойствах ‘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 8601. Чтобы учесть этот момент, все наши функции времени будут принимать формат как параметр, и вывод также я оформил соответствующим образом.

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 параметра:

  • $type
  • $format
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;
}

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

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

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

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

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

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

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

Заключение

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

Источник: WP.tutsplus.com
VN:F [1.9.22_1171]
Rating: 4.9/5 (19 votes cast)

Как правильно интегрировать сниппеты Google в тему WordPress, 4.9 out of 5 based on 19 ratings

Вам понравился материал?
  • http://wp-admin.com.ua/ Уроки WordPress

    Статья бомба! Спасибо, возьму на заметку.

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
  • Виталий

    Попробовал создать новый файл recipe-config.php, в начале надо ставить

    Если так, то чтото весь сайт скривился и в админке не появилась вкладка рецепт,а просто надпись с кодами сверху админки, что не так сделал?

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
    • Виталий

      Вот е вас форма комментариев интересная даже элементы php не пропишешь. Получился вопрос не корректный. Я спрашивал Надо ли код заключать в php с характерными

      VA:F [1.9.22_1171]
      Rating: 0.0/5 (0 votes cast)
      • http://wordpresso.org Wordpresso

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

        VA:F [1.9.22_1171]
        Rating: 1.0/5 (1 vote cast)
  • Регина

    Здравствуйте! Помогите пожалуйста! Уже все перепробовала! Как вставить код include ('recipe-config.php'); в функции????

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
    • http://wordpresso.org Wordpresso

      Почитайте этот урок, думаю будет полезно

      wordpresso.org/tutorials/...ra-faylov-temyi/

      VA:F [1.9.22_1171]
      Rating: 0.0/5 (0 votes cast)
      • Регина

        Я все это уже делала, но у меня 'recipe-config.php' в админке сверху в виде кода выходит, как простой текст.

        VA:F [1.9.22_1171]
        Rating: 0.0/5 (0 votes cast)
        • Регина

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

          VA:F [1.9.22_1171]
          Rating: 0.0/5 (0 votes cast)
  • Регина

    Здравствуйте! А возможно ли вывести мета-блоки не создавая нового шаблона записи, то есть в обычном шаблоне записей?

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)
    • http://wordpresso.org Wordpresso

      Только через CustomPostType

      VA:F [1.9.22_1171]
      Rating: 0.0/5 (0 votes cast)
      • Регина

        Получилось! Просто вставила код метаблоков в функции!

        VA:F [1.9.22_1171]
        Rating: 0.0/5 (0 votes cast)
  • Регина

    Здравствуйте! Я немного изменила код в INGREDIENTS — TEXTAREA ( 'type' => 'textarea' заменила на 'type' => 'repeatable') и теперь не могу отобразить записи на сайте. Не подскажите как это сделать?

    VA:F [1.9.22_1171]
    Rating: 0.0/5 (0 votes cast)