it-swarm.com.ru

Блок из нескольких материалов

Я пытаюсь создать пользовательский тип записи и хотел бы, чтобы этот тип публикации имел два блока контента. Так что в цикле я могу запросить контент-1 и контент-2 отдельно.

Я могу написать код, просто не понимая, как мне начать, то есть есть ли способ легко добавить еще один блок "публикация контента". Должен ли я удалить существующий блок содержимого и использовать два настраиваемых поля (могут ли настраиваемые поля иметь кухонную раковину?)?

Спасибо!

2
Omar Mir

Я бы оставил поле основного содержимого и добавил метабокс + дополнительный экземпляр редактора wp (используя удобную функцию wp_editor ).

Значения настраиваемых полей хранятся в базе данных как LONGTEXT , поэтому они могут обрабатывать практически все, что вы хотите в них бросить.

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

<?php
class Secondary_Content
{
    // meta key we'll use to save things.
    const META = '_secondary_content';

    // nonce name to check
    const NONCE = '_s_content_nonce';

    // post type to which we'll add the box
    const TYPE = 'page';

    private static $ins = null;

    public static function init()
    {
        add_action('plugins_loaded', array(self::instance(), '_setup'));
    }

    public static function instance()
    {
        is_null(self::$ins) && self::$ins = new self;
        return self::$ins;
    }

    public function _setup()
    {
        // we'll add actions here later.
    }
}

Чтобы добавить мета-поле, подключитесь к add_meta_boxes_{{YOUR_POST_TYPE}}. Я просто собираюсь использовать страницы для этого примера. Измените значение константы TYPE в классе, чтобы она работала для пользовательского типа записи.

<?php
class Secondary_Content
{
    // snip snip

    public function _setup()
    {
        add_action('add_meta_boxes_' . self::TYPE, array($this, 'add_box'));
    }

    /**
     * Adds a meta box to the `page` post type.
     *
     * @uses    add_meta_box
     * @return  void
     */
    public function add_box()
    {
        add_meta_box(
            'secondary-content',
            __('Secondary Content', 'wspe'),
            array($this, 'box_cb'),
            self::TYPE,
            'normal',
            'high'
        );
    }

    /**
     * Metabox callback function.
     *
     * @access  public
     * @param   object $post The current $post
     * @uses    get_post_meta
     * @uses    wp_editor
     * @return  void
     */
    public function box_cb($post)
    {
        wp_nonce_field(self::NONCE . $post->ID, self::NONCE, false);

        wp_editor(
            get_post_meta($post->ID, self::META, true),
            self::META
        );
    }
}

Обратный вызов метабокса также включен выше. Это просто выдает одноразовый номер для нас, чтобы проверить, а также поле редактора, используя wp_editor.

Теперь нам просто нужно подключиться к save_post и сохранить вещи. Мы проверим, чтобы убедиться, что мы находимся на правильном типе сообщения. Затем проверьте одноразовый номер и проверьте, есть ли у текущего пользователя разрешение на редактирование сообщения, тогда достаточно просто вызвать update_post_meta или delete_post_meta в зависимости от ситуации. Единственное, что следует отметить, это то, что я проверяю, может ли текущий пользователь публиковать нефильтрованный HTML. Если они могут, я просто позволю всему пройти в метабоксе. Если нет, лучше запустите его через wp_filter_post_kses .

<?php
class Secondary_Content
{
    // snip snip

    public function _setup()
    {
        add_action('add_meta_boxes_' . self::TYPE, array($this, 'add_box'));
        add_action('save_post', array($this, 'save'), 10, 2);
    }

    // snip snip

    /**
     * Hooked into `save_post`.  Makes sure this is the request we want and the
     * user has permission, then saves the custom field.
     *
     * @access  public
     * @param   int $post_id
     * @param   object $post
     * @uses    wp_verify_nonce
     * @uses    current_user_can
     * @uses    update_post_meta
     * @uses    delete_post_meta
     * @return  void
     */
    public function save($post_id, $post)
    {
        if(
            self::TYPE != $post->post_type ||
            (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
        ) return;

        if(
            !isset($_POST[self::NONCE]) ||
            !wp_verify_nonce($_POST[self::NONCE], self::NONCE . $post_id)
        ) return;

        if(!current_user_can('edit_post', $post_id))
            return;

        if(!empty($_POST[self::META]))
        {
            update_post_meta(
                $post_id,
                self::META,
                current_user_can('unfiltered_html') ?
                    $_POST[self::META] : wp_filter_post_kses($_POST[self::META])
            );
        }
        else
        {
            delete_post_meta($post_id, self::META);
        }
    }
}

Чтобы получить это на внешнем интерфейсе, вам просто нужно сделать echo get_post_meta($post->ID, '_secondary_content', true); где-нибудь в цикле. Но было бы лучше включить функцию-оболочку в наш класс.

<?php
class Secondary_Content
{
    // snip snip

    /**
     * Meant to be used as a template tag. A simple helper to spit out our
     * secondary content.
     *
     * @access  public
     * @param   object $post
     * @param   bool $echo (optional) defaults to true.
     * @uses    get_post_meta
     * @return  string
     */
    public static function content($post, $echo=true)
    {
        $res = apply_filters('secondary_content',
            get_post_meta($post->ID, self::META, true));

        if($echo)
            echo $res;

        return $res;
    }
}

Теперь вы можете просто сделать Secondary_Content::content($post);, чтобы получить что-то.

Последнее замечание: этот контент не получит ничего хорошего, как wpautop или тому подобное. Если вы хотите сделать это, вам нужно добавить это в качестве фильтра к окончательному выводу.

<?php
add_filter('secondary_content', 'wpautop');

Конечный результат:

Secondary Content

Все вышеперечисленное как плагин .

6
chrisguitarguy