投稿のすべてのカスタムフィールドをフィルタリングする方法はありますか?
私が持っている非常に基本的な単純さのために仮定しよう:
の標準フィールド:
カスタムフィールド:
ページの読み込み時に、各カスタムフィールドの値の最後に123456を追加するとしますが、これはフィルタを使用して行うとします。どのadd_filterでこれを達成できますか?ちょっとしたコードの書き方が役に立つでしょう。
現在のトップアンサーに従って編集してください:
一番上の答えを見つけた後、私はそれが最初の分野でしか働かない問題に出くわしました。私はそれから私が各要素を通過する必要があることに気づきました、そしてこれは私が持っているものです。奇妙なのは、データが損なわれていないように見えますが、ページに新しいデータが表示されないことです。以下のコードにコメントがあります。
function my_post_meta_filters($null, $post_id, $key, $single){
if(is_admin() || (substr($key, 0, 8) != '_author_' && substr($key, 0, 7) != '_quote_')){
return $null;
}
static $filtered_values = NULL;
if(is_null($filtered_values)){
$cache = update_postmeta_cache(array($post_id));
$values = $cache[$post_id];
//must loop through all the fields or else only the first field is affected
foreach($values AS $valkey => $value){
if(substr($key, 0, 8) == '_author_' || substr($key, 0, 7) == '_quote_'){
$filtered[$valkey] = filtered($values[$valkey][0]);
$filtered[$valkey] = maybe_serialize($filtered[$valkey]); //at this point the data is correct and even reserialized where expected
$filtered_values[$valkey] = $filtered[$valkey];
}
}
return $filtered_values;
}
}
add_filter('get_post_metadata', 'my_post_meta_filters', 0, 4);
function filtered($it){
if(!is_array($it) && !is_serialized($it)){
$filtered = apply_filters('number_filter', $it); //adds numbers to the end
} else {
//otherwise we ran into a serialized array so lets unserialize and run each part through our function
$unserialized = maybe_unserialize($it);
$filtered = array_map('filtered', $unserialized);
}
return $filtered;
}
内部的にポストメタは、ほとんどフィルタリングできないオブジェクトキャッシュを介して処理されます。
投稿メタデータをフィルタリングする唯一の機会は、 'get_post_metadata'
を使用することですが、メタデータが利用できないときにそのフィルタがトリガーされるので、フィルタリングするものはありません。それらをフィルタリングすることよりも結果を短絡することを意図していました。
だから私が提案する解決策は:
そこで、まずフィルタを追加します。
add_filter( 'get_post_metadata', 'my_post_meta_filters', 0, 4 );
それからフッキングコールバックを書きます
function my_post_meta_filters( $null, $pid, $key, $single ) {
if ( ! in_array( $key, array( 'author', 'ISBN', 'quote', '' ), TRUE ) || is_admin() ) {
return $null;
};
static $filtered_values = NULL;
if ( is_null( $filtered_values ) ) {
$cache = update_meta_cache( 'post', array( $pid ) );
$values = $cache[$pid];
$raw = array(
'author' => isset( $values['author'] ) ? $values['author'] : NULL,
'ISBN' => isset( $values['ISBN'] ) ? $values['ISBN'] : NULL,
'quote' => isset( $values['quote'] ) ? $values['quote'] : NULL,
);
// this is the filter you'll use to filter your values
$filtered = (array) apply_filters( 'my_post_meta_values', $raw, $pid );
foreach ( array( 'author', 'ISBN', 'quote' ) as $k ) {
if ( isset( $filtered[$k] ) ) $values[$k] = $filtered[$k];
}
$filtered_values = $values;
}
if ( $key === '' )
$filtered_values;
if ( ! isset( $filtered_values[$key] ) )
return;
return $single
? maybe_unserialize( $filtered_values[$key][0] )
: array_map( 'maybe_unserialize', $filtered_values[$key] );
}
この関数をコードに含めると、カスタム'my_post_meta_values'
フィルタを使用してカスタムフィールドをフィルタできます。
ほんの一例です。
add_filter( 'my_post_meta_values', function( $values, $post_id ) {
// append '123456' to all values
if ( is_array( $values['author'] ) ) {
$values['author'][0] .= ' 123456';
}
if ( is_array( $values['ISBN'] ) ) {
$values['ISBN'][0] .= ' 123456';
}
if ( is_array( $values['quote'] ) ) {
$values['quote'][0] .= ' 123456';
}
return $values;
}, 10, 2 );
このフィルタを有効にして、次の操作を行います。
echo get_post_meta( $post_id, 'author', TRUE );
そしてあなたの "author"カスタムフィールドは "Shawn"に設定されていますが、出力は "Shawn 123456"です。
my_post_meta_filters
は get_post_custom
とも互換性があることに注意してください。