web-dev-qa-db-ja.com

複数コンテンツブロック

カスタム投稿タイプを作成しようとしていますが、その投稿タイプに2つのコンテンツブロックを含めるようにします。そのため、ループ内でcontent-1とcontent-2を別々に要求できます。

私はどうやって始めればいいのかを考え出すのに苦労してコードを書くことができます。既存のコンテンツブロックを削除して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にフックしてものを保存するだけです。正しい投稿タイプであることを確認します。その後、nonceを検証し、現在のユーザーが投稿を編集する権限を持っているかどうかを確認します。その後、必要に応じて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