CMS関連

メニューをカスタマイズ(WordPress)

WordPressの外観>メニューで作ったメニューは、wp_nav_menu関数で簡単出力されます。

階層も反映されてて便利なのですが、どうしてもこの関数は実現できないことが発生したため、独自に関数を作ることにしました。

メニューをデータを取得するには、wp_get_nav_menu_itemsを使用して配列で取得します。

ただし階層構造にはなってません。

なので、以前の記事「WordPressのサイトマップを作る【プラグインなし】」を参考に、階層構造で作り直して出力します。


function my_wp_nav_menu($menu_type, $menu_item_parent = 0, $ul_use_flag = 0){
	
	$return = "";
	$menu_items = wp_get_nav_menu_items('main_navi');
	$menu_trees = array();
	
	if($menu_items){
		$exist_flag = 0;
		foreach($menu_items as $menu_item){
			
			//親が引数($menu_item_parent)と同じもののみ
			if($menu_item_parent == $menu_item->menu_item_parent){
				if($exist_flag == 0){
					if($ul_use_flag == 1) $return .= '<ul class="sub-menu">'."\r\n";
					$exist_flag = 1;
				}
				
				//リンクの開き方
				$target = '';
				if($menu_item->target){
					$target = 'target="_blank"';
				}
				
				//class
				$class = 'menu-item';
				if($menu_item->classes[0]){
					$class .= ' '.implode(" ", $menu_item->classes);
				}
				
				//title要素
				$attr_title = '';
				if($menu_item->attr_title){
					$attr_title = 'title="'.$menu_item->attr_title.'"';
				}
				
				$return .= '<li class="'.$class.'"><a href="'.$menu_item->url.'" '.$target.' '.$attr_title.'>'.$menu_item->title."</a>";
				
				$return .= my_wp_nav_menu($menu_type, $menu_item->ID, 1);
				
				$return .= '</li>'."\r\n";
			}
		}
		if($exist_flag == 1){
			if($ul_use_flag == 1) $return .= '</ul>'."\r\n";
		}
	}
	
	return $return;
}

使用する場合は以下の通り

<ul>
	<?php echo my_wp_nav_menu('main_navi'); ?>
</ul>

これで大体wp_nav_menu関数の標準設定と同じ挙動となります。

再帰のたびに、wp_get_nav_menu_itemsで全部取りなおすので、あんまり効率は良くないですが、とりあえずこれで改造し放題です。

総合管理者 | 2015年07月08日 | コメント(0) | トラックバック(0) | CMS関連 | PHP関連

投稿件数が0件の時、archive.phpでpost_typeを取得する方法

投稿件数が0件のカスタム投稿ページを開いた場合、archive.phpでは、get_post_type()の返り値がfalseとなり、post_typeが取得できません。

その場合は、

get_query_var('post_type')

で取得できるようになります。

こういうケースは結構あるので、get_post_type()ではなくこっちで取得するようにしたほうが良いですね。

 

参考サイト

総合管理者 | 2015年07月02日 | コメント(0) | トラックバック(0) | CMS関連

wp_list_categories・get_categoriesでデータが取得できない

WordPressであり、Wordpressとは関係ない話。

WordPress管理画面の「カテゴリー」画面で、カテゴリー一覧にまったく表示されない現象になってしまいました。

wp-config.phpでデバッグをtrueにしても、Noticeが並ぶだけで何もエラーは表示されない。

フロントエンドでも、wp_list_categories・get_categoriesが使えない状態に。

これまでの経験でいえば、カテゴリーの並び替え系プラグインが原因で、一度並び替えを行って保存すると直ることが多いのですが、今回はそれでも直らない。

仕方ないので、Wordpress本体の中身を追っていくうち、wp-includes/taxonomy.phpの中にあるfunction get_termsにSQLが書かれていたので、出力して、phpMyAdminで実行したところ、以下のエラーが表示されました。

Got error 28 from storage engine

調べてみたところ、サーバの容量が不足していると起こる現象のようです。

参考元:MySQLで「Got error 28 from storage engine…」と出るときの対処法

Tera Termで「df -h」を実行したところ、確かに100%になってました・・・

クライアントのサーバなので、勝手にファイルを削除するわけにもいかないから、とりあえず削除してよいか問い合わせているところ。

まさかこんなところが原因とは。

プラグインやテーマが原因かと思って、切ったりつけたり編集したり、無駄に時間食った・・・

総合管理者 | 2015年03月15日 | コメント(0) | トラックバック(0) | CMS関連 | DB関連 | サーバー関連

WordPressの検索機能をカスタマイズ

WordPressの検索の欠点として

  • カスタムフィールドが対象外
  • カテゴリー・タグ(タクソノミー)が対象外

というものがあります。

最近は内容フィールドは使用せず、カスタムフィールドに中身を入れるといった場合もあるので、これでは大変不便です。

ということで、検索機能をカスタマイズし、これらからも引っ張ってくるようにします。(ついでに抜粋からも)

なお、検索処理のカスタマイズは「pre_get_posts」をフックした関数にて行います。

pre_get_postsについては、こちらをご覧ください(query_postsを捨てよ、pre_get_postsを使おう【追記あり】【報告あり】)。

functions.phpに下記を追加します。
※pre_get_postsをフックした関数がすでに存在していている場合は、うまく編集してください。

function my_pre_get_posts($query) {
	//管理画面には適応しない
	if ( is_admin() || ! $query->is_main_query() )
		return;
		
	//検索画面の場合
	if($query->is_search()){
		global $wpdb;
		
		$keywords = get_search_query();
		if($keywords){
			
			$keywords = str_replace(" ", " ", $keywords);
			$keyword_array = explode(" ", $keywords);
			$post_ids = array();
			$post_ids_exists = array();
			foreach($keyword_array as $keyword){
				$post_ids_meta = array();	//カスタムフィールド
				$post_ids_post = array();	//タイトル・内容
				$post_ids_term = array();	//カテゴリー
				
				if($keyword){
					$keyword = '%' . like_escape( $keyword ) . '%';
					
					//カスタムフィールド内を検索
					$post_ids_meta = $wpdb->get_col( $wpdb->prepare( "
						SELECT DISTINCT post_id FROM {$wpdb->postmeta}
						WHERE meta_value LIKE '%s'
					", $keyword ) );
					
					//タイトルと内容・抜粋から検索
					$post_ids_post = $wpdb->get_col( $wpdb->prepare( "
						SELECT DISTINCT ID FROM {$wpdb->posts}
						WHERE post_title LIKE '%s'
						OR post_content LIKE '%s'
						OR post_excerpt LIKE '%s'
					", $keyword, $keyword, $keyword ) );
					
					//カテゴリー名から検索
					$term_ids = $wpdb->get_col( $wpdb->prepare( "
						SELECT DISTINCT term_id FROM {$wpdb->terms}
						WHERE name LIKE '%s'
					", $keyword) );
					//ヒットしたカテゴリーが所属する投稿
					if($term_ids){
						$term_id = implode(",", $term_ids);
						$post_ids_term = $wpdb->get_col( $wpdb->prepare( "
							SELECT DISTINCT  object_id FROM {$wpdb->term_relationships}
							WHERE term_taxonomy_id IN (%s) 
						", $term_id) );
					}
					
					//各処理で取得した投稿IDをマージする。
					$post_ids_tmp = array();
					$post_ids_tmp = array_merge($post_ids_meta, $post_ids_post, $post_ids_term);
					
					//重複している投稿IDのみ抜き出す(AND検索のため)
					if($post_ids_tmp){
						//検索ワード1つ目の場合、$post_ids_existsのキーに投稿IDを入れていく(内容はtrue)
						if(empty($post_ids_exists)){
							foreach($post_ids_tmp as $post_id){
								$post_ids_exists[$post_id] = 1;
							}
						}
						//検索ワード2つ目以降の場合
						else{
							//○つ目の投稿IDを$post_ids_exists_tmpキーに入れていく(内容はtrue)
							$post_ids_exists_tmp = array();
							foreach($post_ids_tmp as $post_id){
								$post_ids_exists_tmp[$post_id] = 1;
							}
							
							//1つ目の$post_ids_existsと、○つ目の$post_ids_exists_tmpとを比較し、存在しない場合はunsetする。
							foreach($post_ids_exists as $post_id => $value){
								if($post_ids_exists_tmp[$post_id] != 1){
									unset($post_ids_exists[$post_id]);
								}
							}
						}
					}
				}
			}
			
			//まとめた$post_ids_existsのキー(投稿ID)を、内容に移す
			if($post_ids_exists){
				foreach($post_ids_exists as $post_id => $value){
					$post_ids[] = $post_id;
				}
			}
			if($post_ids){
				$query->set('post__in', $post_ids);
			}else{
				$query->set('post__in', array(0));
			}
			
			
		}else{
			$query->set('post__in', array(0));
		}
		$query->set('s', '');	//本来の検索は邪魔になるので削除しておく
	}
}
add_action( 'pre_get_posts', 'my_pre_get_posts' );

最後に、

$query->set('s', '');

を行っているため、検索結果ページで、$sやget_query_var('s')から検索ワードを取得できなくなっています。

そのため、search.phpのget_header()の前に

$wp_query->query_vars["s"] = $wp_query->query["s"];

を追記してください。
これで$sやget_query_var('s')を使って検索ワードを取得できるようになります。

しかし結構ごつい処理をしてるので重くなりそうな気も・・・大丈夫かな。

参考サイト

nandani | 2014年12月17日 | コメント(2) | トラックバック(0) | CMS関連

Firefoxは勝手にアクセスする

WordPressで、独自にページアクセス数をカウントする機能を作成していたのですが、1ページにアクセスしただけなのに、次のページまで加算されてしまう現象になってしまいました。

どうもwp_head()があると、別のページも加算されてしまう模様。

しかし怪しいところは無い。なぜだ・・・と思っていたら、こんな記事を見つけました。

Firefoxはlink relを先読みする模様

お、おう・・・マジか。

なんてありがた迷惑な機能・・・

とりあえずrel="next"を消す必要があるようなので、こちらのサイト(Firefoxはlink relを先読みする模様)を参考にfunctions.phpに下記を追記しました。

remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');

う~ん。

今回SEO対策を考慮しなくてよいサイトだったのでよかったのですが、rel="next" rel="prev"は本来必要な記述。

SEOを考慮しながら、独自でアクセス数をカウントする機能を追加しなくてはならない場合のことも考えておかねば。

ちなみに、アクセスごとにカウントを取る仕組みは、single.phpに


$pageview_prev = get_post_meta($post->ID, "pageview", "true");
$pageview = $pageview_prev + 1;
update_post_meta($post->ID, 'pageview', $pageview, $pageview_prev);

を追記するだけの簡単なものです。

Google Analyticsとかどうしてるんだろう?

まあ賢いGoogle先生だから何かしらのフィルタリングをしているのだろうけど。

nandani | 2014年12月15日 | コメント(0) | トラックバック(0) | CMS関連

カスタムフィールド並び替えが数字の場合の注意点【WordPress】

カスタムフィールド順に並び替える場合、query_postsを使うと、こんな感じになります。

query_posts(
array(
"orderby" => "meta_value",
"meta_key" => "(カスタムフィールドのキー)",
"order" => "ASC"
)
);

しかし各投稿のカスタムフィールドの中身が、1,2,3,4,5,6,7,8,9,10,11,12・・・

となっている場合、順番が

1,11,12,2,3,4,5,6,7,8,9・・・

となってしまいます。

このような場合、orderbyはmeta_valueではなく、meta_value_numとしなくてはなりません。

query_posts(
array(
"orderby" => "meta_value_num",
"meta_key" => "(カスタムフィールドのキー)",
"order" => "ASC"
)
);

これで、並び替えの内容が数字と判断され、数字の順番通りに並びます。

参考サイト

query_posts:WordPress私的マニュアル

テンプレートタグ/query posts - WordPress Codex 日本語版

 

 

nandani | 2014年12月15日 | コメント(0) | トラックバック(0) | CMS関連

管理画面の投稿やカテゴリー(カスタムタクソノミー)画面でも並び替えを反映させる【WordPress】

カテゴリーおよびカスタムタクソノミーの並び替えを簡単に行えるプラグイン「PS Taxonomy Expander

フロントエンドでは、get_termsやwp_list_categoriesの"orderby"を"order"にすることによって、並び替えた順に並んでくれます。

しかし管理画面の「新規投稿を追加」や「投稿を編集」のカテゴリー選択リスト、および「カテゴリー」画面のカテゴリーリストでは並び順が反映されていません。

Category Order and Taxonomy Terms Order」というプラグインもあって、これを使用すると管理画面内の並び順も反映されるんですけどね。

こっちを使ってもいいし、「PS Taxonomy Expander」のまま、functions.phpに下記を追加しても構いません。


function my_get_terms_orderby($orderby){
  if(is_admin()){
    return "t.term_order";
  }else{
    return $orderby;
  }
}
add_filter('get_terms_orderby', 'my_get_terms_orderby', 10);

これで管理画面内のカテゴリーの並び順は強制的に、Term Orderで設定した並び順に並びます。

※必ず一度は並び替えの保存を行ってください。未保存のままだとカテゴリーリストが表示されなくなります。

しかしフック機能の便利さには舌を巻きますね。何でもできる気分になりますw

nandani | 2014年12月02日 | コメント(0) | トラックバック(1) | CMS関連 | PHP関連

ページのスラッグからデータを引き出す方法【WordPress】

get_page_by_path("スラッグ名");

で、そのスラッグ名のページ(固定ページ)を取得できます。

第3引数をpostとすれば、「投稿」から取得できます。

get_page_by_path("スラッグ名", "OBJECT", "post");

なお、固定ページで、親ページが設定されている場合、親ページのスラッグも含める必要があります。

get_page_by_path("親ページのスラッグ名/スラッグ名");

だから、やっぱり正確にはスラッグ名ではないんですね。

 

参考サイト

get_page_by_path:WordPress私的マニュアル

nandani | 2014年11月24日 | コメント(0) | トラックバック(0) | CMS関連 | PHP関連

WordPressでTinyMCEの入力フィールドを作る場合

任意の場所に、Wordpressの内容入力フィールドと同じようにリッチテキストエディタ(TinyMCE)を設置する方法は、

wp_editor( "(内容)", '(ID)');

で、設置できます。

第3引数に細かい設定ができますが、(ID)をnameと同じにしていればこれだけでもOKです。

プラグインなしでカスタムフィールド作ってた際(functions.phpに直書き)どうやったらリッチテキストエディタになるのか、かなり苦戦したのでメモ。

参考サイト

wp_editor:WordPress私的マニュアル

 

nandani | 2014年11月12日 | コメント(0) | トラックバック(0) | CMS関連 | PHP関連

初期テーマの設定【WordPress】

WordPressの初期テーマは、「twentyxxxx」のような、最初から入っているテーマに設定されています。

これはこのテーマを削除しても、インストール直後はそのテーマが選択されている状態となります。

1サイト・1Wordpressなら、特に初期テーマは気にしなくてもよいのですが、マルチサイト化する場合は、初期テーマを任意のものにしたい、かもしれません。どのサイトもテーマを統一したいのに追加するたびに、テーマを選択しなくてはなりませんからね。

ということで、Wordpress本体の中から、設定されている場所を探します。

wp-includes/default-constants.php

の中に、

define( 'WP_DEFAULT_THEME', 'twentyfourteen' );

という記述があります。

これがテーマの初期設定です。

これを変えれば、初期テーマを変えることができるのですが、Wordpressをアップデートするたびに修正するのは面倒なので、wp-config.phpにこれを追記します。

define( 'WP_DEFAULT_THEME', 'xxxxxxxx' );

xxxxxxxxには、初期テーマにしたいテーマのフォルダ名を記述してください。

これで、こちらの設定が優先されます。

nandani | 2014年09月12日 | コメント(0) | トラックバック(0) | CMS関連

Copyright(c) 2010 - 2017 ダリの雑記