WordPress のカスタムフィールドをプレビュー対象にする

カスタムフィールドを使って、使いやすくはしてみたものの、「プレビューに反映されないんですけど!?」と言われてお嘆きの貴方に。

function get_preview_id( $post_id ) {
	global $post;
	$preview_id = 0;
	if ( $post->ID == $post_id && is_preview() && $preview = wp_get_post_autosave( $post->ID ) ) {
		$preview_id = $preview->ID;
	}
	return $preview_id;
}


function get_preview_postmeta( $return, $post_id, $meta_key, $single ) {
	if ( $preview_id = get_preview_id( $post_id ) ) {
		if ( $post_id != $preview_id ) {
			$return = get_post_meta( $preview_id, $meta_key, $single );
		}
	}
	return $return;
}
add_filter( 'get_post_metadata', 'get_preview_postmeta', 10, 4 );


function save_preview_postmeta( $post_ID ) {
	global $wpdb;

	if ( wp_is_post_revision( $post_ID ) ) {
		$wpdb->query( "DELETE FROM $wpdb->postmeta WHERE post_id = $post_ID" );
		$post_metas = apply_filters( 'preview_post_meta_keys', array( 'meta' ) );
		foreach ( $post_metas as $post_meta ) {
			foreach ( $_POST[$post_meta] as $meta_id => $meta_arr ) {
				add_metadata( 'post', $post_ID, $meta_arr['key'], $meta_arr['value'] );
			}
		}
		do_action( 'save_preview_postmeta', $post_ID );
	}
}
add_action( 'wp_insert_post', 'save_preview_postmeta' );

デフォルトのUIに対応させただけのものなので、Custom Field TemplateEditor TemplatesAdvanced Custom Fields での入力値に対応させたい場合は、save_preview_postmeta フックで、それぞれのプラグインの送信形式に合わせて、add_metadata(add_post_meta だと、公開中のデータを上書きしちゃうので注意)を実行するようにしてください。

※ 画像表示に影響が出るため、コードを一部修正しました。(2013/1/8)

WordPressでカスタムフィールドも検索対象にする

WordPressでカスタムフィールドも検索対象に含めてみました。

といっても、全てのカスタムフィールドを検索対象にするといろいろとアレなので、特定の名前を持つもののみに限定しなければなりません。
そこは、

pm.meta_key IN ( 'meta_key1', 'meta_key2', 'meta_key3' )

の meta_keyn の部分を調整してもらえれば、大丈夫だと思います。

function search_custom_field_query( $search, $wp_query ) {
	if ( $wp_query->is_main_query() && $wp_query->is_search() && ! is_admin() ) {
		$q = $wp_query->query_vars;
		$n = !empty($q['exact']) ? '' : '%';

		$add_search = '';
		foreach( (array) $q['search_terms'] as $term ) {
			$term = esc_sql( like_escape( $term ) );
			$add_search = " OR ( pm.meta_key IN ( 'meta_key1', 'meta_key2', 'meta_key3' ) AND pm.meta_value LIKE '{$n}{$term}{$n}')";
		}
		$search = str_replace( ')))', ')' . $add_search . '))', $search );
	}
	return $search;
}
add_filter( 'posts_search', 'search_custom_field_query', 10, 2 );


function search_custom_field_join( $join, $wp_query ) {
	global $wpdb;
	if ( $wp_query->is_main_query() && $wp_query->is_search() && ! is_admin() ) {
		$join .= " INNER JOIN {$wpdb->postmeta} AS pm ON pm.post_id = {$wpdb->posts}.ID";
	}
	return $join;
}
add_filter( 'posts_join', 'search_custom_field_join', 10, 2 );

/*
 * 
 */
function search_custom_field_groupby( $groupby, $wp_query ) {
	global $wpdb;
	if ( $wp_query->is_main_query() && $wp_query->is_search() && ! is_admin() ) {
		$groupby = "{$wpdb->posts}.ID";
	}
	return $groupby;
}
add_filter( 'posts_groupby', 'search_custom_field_groupby', 10, 2 );

え?Search Everything 使えって?