web-dev-qa-db-ja.com

カスタム投稿タイトルとしてカスタムフィールドを使用する

私はWPAlchemyクラスを使って一連のカスタムフィールドでカスタム投稿タイプを設定しました。カスタムフィールドの1つの値を取得し、それを投稿のタイトルとして使用しようとしています。しかし、これまでのところ、私は成功していません。私はあちこちを見回していて、私は次の2つの異なるコードブロックを試してみました。

function custom_post_type_title ( $post_id ) {
    global $wpdb;
    if ( get_post_type( $post_id ) == 'listing' ) {
        $title = get_post_meta($post_id, 'listing_name', true);
        $where = array( 'ID' => $post_id );
        $wpdb->update( $wpdb->posts, array( 'post_title' => $title ), $where );
    }
}

add_action('init', 'listing_save_post');
function listing_save_post( $post_id ) {
        if ( ! defined( 'DOING_AUTOSAVE' ) && ! DOING_AUTOSAVE ) return;
        add_action('save_post', 'custom_post_type_title', 100);
        add_action('publish_post', 'custom_post_type_title', 100);
}

そして、(一時的にnonceフィールドをコメントアウトして、それらがどのように機能するのか理解するまで)

add_filter('wp_insert_post_data', 'change_title', 99, 2);
function change_title($data, $postarr)
{    
    // If it is our form has not been submitted, so we dont want to do anything
    if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return;

    // Verify this came from the our screen and with proper authorization because save_post can be triggered at other times
   // if(!isset($_POST['my_nonce_field'])) return;

    // If nonce is set, verify it
   // if(isset($_POST['my_nonce_field']) && !wp_verify_nonce($_POST['my_nonce_field'], plugins_url(__FILE__))) return;

       // Combine address with term
    $title = $_POST['listing_name'];
    $data['post_title'] = $title;

    return $data;
}

どちらの場合も、結果は同じです。

  1. 新しい投稿を保存すると、ページがリロードされ、動作したと表示され、すべてのカスタムフィールドが空になります。 (どちらのコードセットも実行していなくても、カスタム投稿は問題なく機能し、フィールドは保存されます)。

  2. カスタム投稿タイプインデックスを表示すると、投稿がありません。

何か案は?

_アップデート_

はっきりさせるために、私はカスタムの投稿withoutを使っています。それでも、カスタムフィールドの値を使用して、タイトルフィールドに入力しようとしています。

3
Jonathan Wold

そのため、投稿を保存するたびに、保存したばかりのタイトルの値をカスタムフィールドの別の値に置き換える必要があります。

実際のタイトルフィールドには、タイトルを何にしても構いません。

しかし私はこれがプレゼンテーション目的のためであると思います:あなたはそのカスタム投稿タイプがカスタムフィールドの値に基づいてフロントエンドに異なるタイトルを表示することを望みます。これを実現するための簡単な方法はフィルタです。

一般的なテンプレートタグであるthe_titleは、get_the_titleというフィルタを含むthe_titleを囲む非常に薄いラッパーです。実際のタイトルと投稿IDの2つの引数を取ります。それに引っ掛かり、あなたのカスタムフィールドに基づいてタイトルを変更してください。

<?php
add_filter( 'the_title', 'wpse33385_filter_title', 10, 2 );
function wpse33385_filter_title( $title, $post_id )
{
    if( $new_title = get_post_meta( $post_id, 'custom_field_name', true ) )
    {
        return $new_title;
    }
    return $title;
}

覚えておくべきあなたのコードについてのいくつかのこと:

アクションは勝手に引数を受け取りません。たとえばinitにフックされた関数は、引数を渡さないでください。 do_actionが呼び出されるとき、最初の引数はフック名です。それに続く引数はあなたが望むならフックされた関数に渡されるものです(4番目のadd_actionのオプション引数で指定されます)。

do_action( 'init' );呼び出しはwp-settings.phpにあります。 見てください 、引数なし。

したがって、この:

<?php
add_action('init', 'listing_save_post');
function listing_save_post( $post_id ) {
        if ( ! defined( 'DOING_AUTOSAVE' ) && ! DOING_AUTOSAVE ) return;
        add_action('save_post', 'custom_post_type_title', 100);
        add_action('publish_post', 'custom_post_type_title', 100);
}

あなたが期待するようには動かないでしょう。さらに、add_actionは関数の中で呼び出しますが、関数の外で独自に呼び出すことができます。これは問題なく機能します。

add_action('save_post', 'custom_post_type_title', 100);
function custom_post_type_title( $post_id ) {
    // do stuff
}

save_postに対してのみ行う必要があり、その場合およびpublish_postに対しては必要ありません。

できれば私はいつも$wpdbに直接行かないようにしています。何回もより便利なAPIがあるからです。あなたがやろうとしていたのは投稿を更新することです。そのため、 wp_update_post を使用してください。あなたの場合、それは有効なオプションではありません(コーデックスが述べているように、それは無限ループを引き起こす可能性があります)。

それはちょっと長い間、残念でした。うまくいけば、それはWordPressのフックシステムに関するいくつかのことを片付けました!

これらのあなたの親友を作ります:

3
chrisguitarguy

あなたのフィルターが御馳走を働かせてくれてありがとう。

ちなみに

ページを編集しているときに、管理者がエントリのタイトルを自分のカスタムの "longtitle"(デフォルト= menu-item-title)に変更しないようにするためのチェックを追加しました。

関数pcdg_filter_title($ title、$ post_id)
 {
 if(!is_admin())
 {
 if($ new_title = get_post_meta( $ post_id、 'longtitle'、true))
 {
 return $ new_title; 
} 
} 
 $ titleを返す; 
 ] add_filter( 'the_title'、 'pcdg_filter_title'、10,2); 
0
PC Doctor Go