Новые поля для редактирования записи


В WordPress есть очень мощный инструмент для создания уникальных типов записей — это произвольные поля или Custom Fields. В новых версиях они незаслуженно скрыты «по умолчанию», видимо чтобы не травмировать пользователя обилием странных полей под визуальным редактором 🙂 И правда, разобраться в том, как они работают, сможет только искушенный пользователь, задача же разработчика — сделать все как можно более практично, например так:

Согласитесь, что так гораздо нагляднее, нежели объяснять пользователю, как создавать, выбирать из списка и заполнять новое произвольное поле. Решение позаимствовано у заграничных коллег с сайта Deluxe Blog Tips, за что им отдельное спасибо. Оно строится на функции add_meta_box(). Ниже мы приведем код, в котором создадим панель индивидуальных SEO настроек для каждой записи блога без плагина. Добавлением полей происходит путем создания новых массивов в $meta_box[‘fields’], и весь код должен быть размещен в файле function.php, в папке с вашей темой.

<?php

//------------------------------------- Улучшаем произвольные поля -------------------------//

$prefix = 'seo_';
$meta_box = array(
    'id' => 'my-meta-box',
    'title' => 'SEO оптимизация',
    'page' => 'post',
    'context' => 'normal',
    'priority' => 'high',
    'fields' => array(

        array(
            'name' => 'Заголовок страницы:',
            'id' => $prefix . 'title',
            'type' => 'text'
        ),
        array(
            'name' => 'Ключевые слова:',
            'id' => $prefix . 'keywords',
            'type' => 'text'
        ),
        array(
            'name' => 'Описание:',
            'id' => $prefix . 'description',
            'type' => 'textarea'
        )
    )
);

add_action('admin_menu', 'mytheme_add_box');

function mytheme_add_box() {
    global $meta_box;

    add_meta_box($meta_box['id'], $meta_box['title'], 'mytheme_show_box',
                 $meta_box['page'], $meta_box['context'], $meta_box['priority']);
}

function mytheme_show_box() {
    global $meta_box, $post;

    // Use nonce for verification
    echo '<input type="hidden" name="mytheme_meta_box_nonce" value="', wp_create_nonce(basename(__FILE__)), '" />';

    echo '<table class="form-table">';

    foreach ($meta_box['fields'] as $field) {
        // get current post meta data
        $meta = get_post_meta($post->ID, $field['id'], true);

        echo '<tr>',
                '<th style="width:20%"><label for="', $field['id'], '">', $field['name'], '</label></th>',
                '<td>';
        switch ($field['type']) {
            case 'text':
                echo '<input type="text" name="', $field['id'], '" id="', $field['id'], '" value="',
 $meta ? $meta : $field['std'], '" size="30" style="width:97%" />',
                    '<br />', $field['desc'];
                break;
            case 'textarea':
                echo '<textarea name="', $field['id'], '" id="', $field['id'], '" cols="60" rows="4"
style="width:97%">', $meta ? $meta : $field['std'], '</textarea>',
                    '<br />', $field['desc'];
                break;
            case 'select':
                echo '<select name="', $field['id'], '" id="', $field['id'], '">';
                foreach ($field['options'] as $option) {
                    echo '<option', $meta == $option ? ' selected="selected"' : '', '>', $option, '</option>';
                }
                echo '</select>';
                break;
            case 'radio':
                foreach ($field['options'] as $option) {
                    echo '<input type="radio" name="', $field['id'], '" value="', $option['value'], '"',
$meta == $option['value'] ? ' checked="checked"' : '', ' />', $option['name'];
                }
                break;
            case 'checkbox':
                echo '<input type="checkbox" name="', $field['id'], '" id="', $field['id'], '"',
$meta ? ' checked="checked"' : '', ' />';
                break;
        }
        echo    '<td>',
            '</tr>';
    }

    echo '</table>';
}

add_action('save_post', 'mytheme_save_data');

// Save data from meta box
function mytheme_save_data($post_id) {
    global $meta_box;

    // verify nonce
    if (!wp_verify_nonce($_POST['mytheme_meta_box_nonce'], basename(__FILE__))) {
        return $post_id;
    }

    // check autosave
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return $post_id;
    }

    // check permissions
    if ('page' == $_POST['post_type']) {
        if (!current_user_can('edit_page', $post_id)) {
            return $post_id;
        }
    } elseif (!current_user_can('edit_post', $post_id)) {
        return $post_id;
    }

    foreach ($meta_box['fields'] as $field) {
        $old = get_post_meta($post_id, $field['id'], true);
        $new = $_POST[$field['id']];

        if ($new && $new != $old) {
            update_post_meta($post_id, $field['id'], $new);
        } elseif ('' == $new && $old) {
            delete_post_meta($post_id, $field['id'], $old);
        }
    }
} 

?>

Теперь нам остается только вывести полученные данные в «шапке» темы: идем в редактирование файла header.php и вставляем следующий код внутри тэга head:

Вместо тэга title:

<?php
        if(is_single()) {
          $title = get_post_meta($post->ID, 'seo_title', true);
          if($title) {
             echo '<title>'.$title.'</title>';
          } else {
             echo '<title>'.get_the_title().'</title>';
          }
        } else {
          echo '<title>'.get_bloginfo('name').'</title>';
        }
?>

Если заполнен SEO заголовок страницы, то будет выводиться он, в противном случае — обычный заголовок записи. На остальных страницах будет выводиться название сайта. Переходим к meta keywords:

<?php
         if(is_single()) {
          $keywords = get_post_meta($post->ID, 'seo_keywords', true);
          if($keywords != "") {
            echo '<meta name="keywords"  content="'.$keywords.'"/>';
          }
         }
?>

Если «Ключевые слова» не заполнены, тэг meta keywords не выводится. И наконец meta decription:

<?php
          if(is_single() and $description != "") {
            $description = get_post_meta($post->ID, 'seo_description', true);
            echo '<meta name="description"  content="'.$description.'"/>';
          } else {
            echo '<meta name="description"  content="'.get_bloginfo('description').'"/>';
          }
?>

Если не заполнено поле «Описание», то будет выводится Краткое описание из меню Параметры — Общие.


Требуется подобная доработка? Напишите нам.


Name

Email


Website


Messagge