変なWPカスタマイズの例を集めてみた。
特定のカスタムタクソノミーを持つ投稿以外のカスタムフィールド名を変更
たとえばバックアップ用途で使用する。
UPDATE `wp_postmeta` SET `meta_key` = 'hoge-after'
WHERE `meta_key` = 'hoge-before'
AND `post_id` NOT IN (
SELECT `object_id` FROM `wp_term_relationships` WHERE `term_taxonomy_id` = 100
);
ただ削除するだけであれば下記。
DELETE FROM `wp_postmeta`
WHERE `meta_key` = 'hoge'
AND `post_id` NOT IN (
SELECT `object_id` FROM `wp_term_relationships` WHERE `term_taxonomy_id` = 100
);
カテゴリーを階層を保って出力する関数
function outputTerms($taxonomy, $_parentTermID = 0) {
$terms = get_terms($taxonomy, array(
'parent' => $_parentTermID,
'hierarchical' => 1,
'hide_empty' => 0,
));
if ($terms) {
echo '<ul>';
foreach($terms as $term) {
echo '<li>';
echo '<a href="' . get_category_link($term->term_id) . '">' . $term->name . '</a>';
outputTerms($taxonomy, $term->term_id);
echo '</li>';
}
echo '</ul>';
}
}
outputTerms('category');
特定のタクソノミーを持つ投稿のURLを変更
add_action( 'pre_get_posts', function( $query ) {
if ( is_admin() || ! $query->is_main_query() ) {
return;
}
if ($query->is_post_type_archive('foo')) {
$query->set('category_name', get_query_var('bar'));
}
} );
add_filter( 'query_vars', function ( $public_query_vars ) {
$public_query_vars[] = 'bar';
return $public_query_vars;
} );
add_filter('rewrite_rules_array', function($rules){
$new_rules = array(
'baz/([^/]+)/?$' => 'index.php?post_type=foo&bar=$matches[1]',
'baz/([^/]+)/page/([0-9]+)/?$' => 'index.php?post_type=foo&bar=$matches[1]&paged=$matches[2]',
);
return $new_rules + $rules;
});
// post_linkフィルターなども使用してURLを変更する
ACFで作ったタームのカスタムフィールドの数値順にタームを並び替え
function itemsList($taxonomy) {
// 番号順に並び替え
$terms = get_terms($taxonomy, array(
'hide_empty' => 0,
));
$orderList = array();
foreach($terms as $term) {
$value = get_field('hoge-priority', $taxonomy . '_' . $term->term_id);
if (is_numeric($value)) {
$value = (int)$value;
} else {
$value = 0;
}
$id = $term->term_id;
$orderList[$id] = $value;
}
arsort($orderList, SORT_NUMERIC);
foreach($orderList as $key => $value) {
// outputItem関数で個別のtermオブジェクトを渡す
outputItem(get_term($key, 'category'));
}
}
itemsList('category');
親子関係のあるカテゴリーでリンクの階層をなくす
// https://example.com/category/parent/child/ -> https://example.com/category/child/
function my_term_link($termlink, $term, $taxonomy) {
return ($taxonomy === 'category' ? home_url('/category/'. $term->slug . '/') : $termlink);
}
add_filter('term_link', 'my_term_link', 10, 3);
// ほんとはリライトルールも変更したほうがいい
カスタムタクソノミー のカスタムフィールド(get_option)などで取得される値を元にクエリを変更する
同じように単純にカスタムフィールドなんかで難しい場合は、投稿idのリストを取得してそのidのみをクエリにするなんかの処理がスマート。
// pre_get_postsで事前に取得してからクエリを発行
add_action('pre_get_posts', function($query) {
if (!is_admin() && $query->is_main_query() && is_tax('foo', 100)) {
$list = array();
$allCategory = get_categories();
foreach($allCategory as $cat) {
$hasBar = get_field('bar', 'category_' . $cat->cat_ID);
if ($hasBar) {
$list[] = $cat->cat_ID;
}
}
$query->set('category__not_in', $list);
}
});
投稿のパーマリンクを変更
パーマリンクを http://example.com/?eid=xx 形式に変更したい場合は、以下のようにして parse_query フィルタを使うと良い。
参考:https://dogmap.jp/2011/04/21/change-category-link-to-different-link/
class add_permalink_to_different_link {
function __construct(){
add_filter('query_vars', array(&$this, 'add_query_vars'));
add_action('parse_query', array(&$this, 'parse_query'));
add_filter('post_link', array(&$this, 'post_link'), 10, 3);
}
public function add_query_vars($qvars) {
$qvars[] = 'eid';
return $qvars;
}
public function parse_query($query) {
$post_id = (int) $query->query_vars['eid'];
if ( !(empty($post_id) || $post_id === 0) ) {
$url = get_permalink($post_id);
if ( !empty($url) && $url !== FALSE ) {
$query->query_vars["p"] = $post_id;
$query->query["p"] = $post_id;
$query->is_single = true;
$query->is_singular = true;
$query->is_home = false;
$query->is_404 = false;
} else {
$query->set_404();
}
}
return $query;
}
public function post_link($permalink, $post, $leavename) {
return ($post->post_type === 'post' ? home_url('/?eid='.$post->ID) : $permalink);
}
}
new add_permalink_to_different_link();
特定のカテゴリーがあるかどうかで投稿の順番を変える
add_action('pre_get_posts', function($query) {
if (is_admin() || !$query->is_main_query()) {
return;
}
// カテゴリーページ
if (is_category()) {
$catId = get_queried_object()->cat_ID;
$target_list = array();
// fooのbarがあれば、優先的に
$target_query = new WP_Query(array(
'cat' => $catId,
'posts_per_page' => -1,
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'foo',
'field' => 'slug',
'terms' => 'bar',
'operator' => 'NOT IN'
),
),
));
if ( $target_query->have_posts() ) :
while ( $target_query->have_posts() ) : $target_query->the_post();
$target_list[] = get_the_ID();
endwhile;
endif;
wp_reset_postdata();
// fooのbazがあれば優先順位を下げる
$target_query = new WP_Query(array(
'cat' => $catId,
'posts_per_page' => -1,
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'foo',
'field' => 'slug',
'terms' => 'baz',
'operator' => 'IN'
),
),
));
if ( $target_query->have_posts() ) :
while ( $target_query->have_posts() ) : $target_query->the_post();
$target_list[] = get_the_ID();
endwhile;
endif;
wp_reset_postdata();
$query->set('post__in', $target_list);
$query->set('orderby', 'post__in');
}
});
カテゴリーを他のポストタイプでも使用できるようにする
add_action('init', function() {
register_taxonomy_for_object_type('category', 'hoge');
}, 10000);
カテゴリーページのパーマリンクを変更
参考:https://dogmap.jp/2011/04/21/change-category-link-to-different-link/
register_taxonomyを使えない場合で、カテゴリのリンクを http://example.com/?cid=xx 形式でも表示できるようにする。
class add_category_link_to_different_link {
function __construct(){
add_filter('query_vars', array(&$this, 'add_query_vars'));
add_action('parse_query', array(&$this, 'parse_query'));
}
public function add_query_vars($qvars) {
$qvars[] = 'cid';
return $qvars;
}
public function parse_query($query) {
$cat_id = (int) $query->query_vars['cid'];
if ( !(empty($cat_id) || $cat_id === 0) ) {
$url = get_category_link($cat_id);
if ( !empty($url) && $url !== FALSE ) {
$query->query_vars["cat"] = $cat_id;
$query->is_404 = false;
} else {
$query->set_404();
}
}
return $query;
}
}
new add_category_link_to_different_link();
カテゴリのリンクを http://example.com/cid/xx 形式に変更する場合。
class add_rewrite_rules{
private $rule = null;
private $query_var = null;
function __construct($rule, $query_var) {
$this->rule = $rule;
$this->query_var = $query_var;
add_filter('rewrite_rules_array', array(&$this, 'rewrite_rules_array'));
add_action('init', array(&$this, 'init'));
}
public function init() {
global $wp_rewrite;
$rules = $wp_rewrite->wp_rewrite_rules();
if (!isset($rules[$this->rule])) {
$wp_rewrite->flush_rules();
}
}
public function rewrite_rules_array($rules) {
global $wp_rewrite;
$new_rules[$this->rule] = $this->query_var;
$rules = array_merge($new_rules, $rules);
return $rules;
}
}
global $wp_rewrite;
new add_rewrite_rules('^cid\/([0-9]+)$', $wp_rewrite->index . '?cat=$matches[1]');
特定の投稿タイプを含めるカスタムクエリ変数を追加
参考:https://chaika.hatenablog.com/entry/2014/10/10/200016
参考:https://qiita.com/shogo/items/403b8244ea39262ba132
// カスタムクエリ変数を追加
add_filter('query_vars', function($vars) {
$vars[] = 'force-post-type';
return $vars;
});
function my_posts_per_page($query) {
if(is_main_query() && is_search() && !is_admin()) {
$query->set( 'post_type', get_query_var('force-post-type', 'post') );
}
}
add_action( 'pre_get_posts', 'my_posts_per_page' );
/**
*
* 検索対象を投稿かカスタムフィールドにするかの分岐
*
**/
function my_posy_search($search, $wp_query) {
if ($wp_query->is_main_query() && $wp_query->is_search() && !is_admin()) {
$q = $wp_query->query_vars;
$n = null;
if ($q['force-post-type'] === 'hoge') {
$search .= ' AND post_type = \'hoge\'';
} else {
$search .= ' AND post_type = \'post\'';
}
}
return $search;
}
add_filter('posts_search', 'my_posy_search', 10, 2);
特定の投稿タイプのみ編集を可能にするユーザーロール
参考:https://fixcode.jp/wordpress/wp-disabled-create_posts/
create_posts権限はregister_post_typeの時に決定するから特別に調整が必要みたい。
function change_post_types_cap() {
global $wp_post_types;
$target_post_types = array('post');
foreach($target_post_types as $target_post_type) {
// create_postsの権限を変更
$cap = &$wp_post_types[$target_post_type]->cap;
$cap->create_posts = "create_posts";
}
// create_posts権限を無効化(hogeグループ)
$role = get_role( 'hoge' );
$role->add_cap( 'create_posts', false );
}
add_action( 'init', 'change_post_types_cap' );
RSSを別ドメインにも許容
参考:https://stackoverflow.com/questions/12517039/how-to-add-cors-support-to-wordpress-rss2-feed
add_action( 'pre_get_posts', 'add_header_origin' );
function add_header_origin() {
if (is_feed()){
header( 'Access-Control-Allow-Origin: *' );
}
}
構造化データのdatePublishedとdateModifiedを出力
echo get_date_from_gmt(get_post_time('c', true), 'c');
echo get_date_from_gmt(get_post_modified_time('c', true), 'c');
誰でも作成者にできるようにする
add_filter( 'wp_dropdown_users_args', 'add_subscribers_to_dropdown', 10, 2 );
function add_subscribers_to_dropdown( $query_args, $r ) {
$query_args['who'] = '';
return $query_args;
}