WordPressを使ったWebサイトにSEO施行する際に役立つっぽいカスタマイズハック

Ads

久々にSEOの記事。以前書いたSEOの
カスタマイズハック記事があるのですが、
あれから2年近く経つので新たに記事と
して、ここに付け加えておくことにします。
SEO自体、情報が不確かなものなので、
これを行えば最適化出来る!という類の
情報は載せません。

SEOもハサミと同様、結局は使い方次第だと思いますのでコンテンツやターゲットによっては役に立ったり立たなかったり、ということがあるかと思いますが、同時にそれが混乱の元にもなってしまいがちです。

ですので、今日はSEOに効果的なカスタマイズではなく、自分でSEO施工をしやすくする、というカスタマイズ方法を書いておきます。Webマスターのアイデア次第で効果のあるハックにもなるし、効果のないハックにもなると思います。

コード自体は基本的に普通のテンプレートタグを使用してるものが大半です。全部施行しても何の意味も無いので、使えそうなハックがあったらお好みで導入してみる、程度にお受け止めください。

内容

テキストだらけなので内容を一覧にしました

  1. h1やh2のテキストを記事ごとに好みのテキストにする
  2. 条件分岐でtitleをハックする
  3. 特定のカテゴリだけインデックスさせない
  4. コメント欄のURLの自動リンク化を禁止する
  5. カテゴリごとに別のファイルを呼び出す
  6. #moreの削除
  7. h2のリンク先を変える
  8. プラグイン無しで簡易LPO
  9. 簡単なパンくず
  10. プラグイン無しでtitleを記事ごとに自由に設定する
  11. プラグイン
  12. おまけ:高速化

h1やh2のテキストを記事ごとに好みのテキストにする

条件分岐とカスタムフィールドを使います。

<h1>
<?php if (get_post_meta($post->ID, "h1", true)) : ?>
<?php $key="h1"; echo get_post_meta($post->ID, $key, true); ?>
<?php else : ?>
<?php the_title(); ?>
<?php endif; ?>
	</h1>

$key=”h1″がカスタムフィールドの名前になります。以前書いた記事ですので詳細は過去記事を御覧ください。

条件分岐でtitleをハックする

便利な条件分岐をtitleに用います。

<title>
<?php if ( is_home() )     { ?><?php bloginfo('name'); ?> | <?php bloginfo('description'); ?><?php } ?>
<?php if ( is_single() )   { ?><?php wp_title(''); ?> | <?php bloginfo('name'); ?><?php } ?>
<?php if ( is_page() )     { ?><?php bloginfo('name'); ?> | <?php wp_title(''); ?><?php } ?>
<?php if ( is_search() )   { ?><?php echo the_search_query(); ?> | <?php bloginfo('name'); ?><?php } ?>
<?php if ( is_category() ) { ?><?php single_cat_title(); ?> | <?php bloginfo('name'); ?><?php } ?>
<?php if ( is_month() )    { ?> <?php the_time('F'); ?> | <?php bloginfo('name'); ?><?php } ?>
<?php if ( is_tag() )      { ?><?php single_tag_title();?> | <?php bloginfo('name'); ?><?php } ?>
</title>

上記はやり過ぎかもですけどコンディショナルタグ(CODEX)を使って各アーカイブや記事、TOPのタイトルを自由に設定した例です。必要に応じて消すなり追加するなりラジバンダr。
シンプルに行くならTOPページと子ページだけ変える、というのでもいいかも知れませんね。

<?php if (is_home()) { ?>
    <title><?php bloginfo('name'); ?> | <?php bloginfo('description'); ?></title>
<?php } else { ?>
    <title><?php wp_title('|', true, 'right'); bloginfo('name'); ?></title>
<?php } ?>

このへんはプラグインで弄れますけど、プラグインの吐き出すコードでソースを汚したくない、という方は上記のような方法で対応してみてください。

特定のカテゴリだけインデックスさせない

header内に記述

<?php if ( is_category('3') || in_category('3') ) {
    echo "<meta name=\"robots\" content=\"noindex\" />\n";
}
?>

インデックスさせたくないカテゴリの記事のみにmeta noindexを加えます。上記はID3のカテゴリにmetaを加えた例。「特定のカテゴリだけインデックスさせない」以外にもいろいろと使える方法です。

コメント欄のURLの自動リンク化を禁止する

functions.phpに記述

remove_filter('comment_text', 'make_clickable', 9);

どうせnofollow付くし、ちゃんと管理すればいいだけなので、いいっちゃいいんですけど気持ち悪い方や事情のある方はどうぞ。

カテゴリごとに別のsingle.phpファイルを呼び出す

カテゴリのコンテンツに沿ったSEO施工をするのであればカテゴリごとにそれぞれsingle-**.phpを作り、構造などをカスタマイズして下さい。作った複数のsingle-**.phpを呼び出す等の施工をsingle.phpにします。

<?php
$post = $wp_query->post;
if ( in_category('1') ) {
include(TEMPLATEPATH . '/single1.php');
} elseif ( in_category('3') ) {
include(TEMPLATEPATH . '/single3.php');
} elseif ( in_category('27') ) {
include(TEMPLATEPATH . '/single3.php');
} elseif ( in_category('2') ) {
include(TEMPLATEPATH . '/single2.php');
} elseif ( in_category('14') ) {
include(TEMPLATEPATH . '/single2.php');
} elseif ( in_category('4') ) {
include(TEMPLATEPATH . '/single4.php');
} elseif ( in_category('15') ) {

       ~中略~

} elseif ( in_category('10') ) {
include(TEMPLATEPATH . '/single10.php');
} elseif ( in_category('11') ) {
include(TEMPLATEPATH . '/single11.php');
} else {
include(TEMPLATEPATH . '/single-other.php');
}
?>

ずらずら書かれてますけど条件分岐+インクルードタグを使ってるだけです。

#moreの削除

functions.phpに記述。

<?php
function custom_content_more_link( $output ) {
    $output = preg_replace('/#more-[\d]+/i', '', $output );
    return $output;
}
add_filter( 'the_content_more_link', 'custom_content_more_link' );
?>

余計なパラメータが付いて被リンクが分散するとイヤーンなのでハッシュがつかないようにします。

h2のリンク先を変える

多くの場合、記事タイトルは以下のようなコードです。

<h2><a href="<?php the_permalink() ?>"><?php the_title(); ?></a></h2>

このテキストを変えずにリンク先だけ変えてしまおう、という方法。ユーザーが混乱するので需要はなさそうですけど、応用的に使えるので書いておきます。

まずfunctions.phpに以下を追加。

function print_post_title() {
	global $post;
	$thePostID = $post->ID;
	$post_id = get_post($thePostID);
	$title = $post_id->post_title;
	$perm  = get_permalink($post_id);
	$post_keys = array(); $post_val  = array();
	$post_keys = get_post_custom_keys($thePostID);

	if (!empty($post_keys)) {
  	  foreach ($post_keys as $pkey) {
    	    if ($pkey=='url' || $pkey=='title_url' || $pkey=='url_title') {
      	      $post_val = get_post_custom_values($pkey);
    	    }
  	  }
  	  if (empty($post_val)) {
    	    $link = $perm;
  	  } else {
    	    $link = $post_val[0];
  	  }
	} else {
  	  $link = $perm;
	}
	echo '<h2><a href="'.$link.'" rel="bookmark" title="'.$title.'">'.$title.'</a></h2>';
}

これで、URLのみをカスタムフィールドで変えることが出来るようになりました。single.phpには最初のh2~のタグの代わりに以下を埋め込みます。

<?php print_post_title() ?>

URLを変えたい記事のカスタムフィールドの名前に「url」、値に変更先のURLを設定すれば変わります。

(via:WP Recipes)

プラグイン無しで簡易LPO

僕は未検証ですけど簡単なLPOを実装出来るみたいです。functions.phpに以下を記述。

function lpo_hack(){
  $ref = $_SERVER['HTTP_REFERER'];
  $SE = array('/search?');
  foreach ($SE as $source) {
    if (strpos($ref,$source)!==false) return true;
  }
  return false;
}

$SEがリファラ元として設定する検索エンジンです。他にあれば適当に追加してください。ここ経由のユーザーにのみコンテンツを表示させます。で、表示させたいコンテンツを以下のようなコードで。

if (function_exists('lpo_hack')) {
  if (lpo_hack()) {
    //表示させたいコンテンツ
  }
}

でも、プラグイン使った方が多分良いです。

(via:scratch99)

簡単なパンくず

SERPsにも表示されるのでパンくずはあったほうがいいですね。

<div class="breadcrumbs">
	<a href="<?php bloginfo('url'); ?>"><?php bloginfo('name'); ?></a> &gt; 
	<?php $cat = get_the_category(); echo get_category_parents($cat[0], true, ' &gt; '); ?>
	<?php the_title(); ?>
</div>

上記コードはお友達のそらいくんが書いてました

カテゴリ等のアーカイブにも対応させるなら

<?php if (is_home()) { ?>
  <a href="<?php bloginfo('url'); ?>">ホーム</a>
<?php } else if (is_page()) { ?>
  <a href="<?php bloginfo('url'); ?>">ホーム</a> &gt; <?php the_title(); ?>
<?php } else if (is_category()) { ?>
  <a href="<?php bloginfo('url'); ?>">ホーム</a> &gt; &rsquo;<?php single_cat_title(); ?>&rsquo;カテゴリー内の記事一覧
<?php } else if (is_month()) { ?>
  <a href="<?php bloginfo('url'); ?>">ホーム</a> &gt; &rsquo;<?php the_time('Y年m月'); ?>&rsquo;月別アーカイブ内の記事一覧
<?php } else if (is_single()) { ?>
  <a href="<?php bloginfo('url'); ?>">ホーム</a> &gt; <?php $c = get_the_category(); echo '<a href="' . get_category_link( $c[0]->term_id ) . '">' . $c[0]->name . '</a>'; ?> &gt; <?php the_title(); ?>
<?php } ?>

みたいにしてあげればいいんじゃないでしょうか。

is_single()の部分だけコードが長いですが、これは普通にthe_category()をそのまま使うと親カテゴリと子カテゴリ全てを表示してしまい、可視性と使い勝手を損なうので親カテゴリのみ抽出するようにしています。

プラグイン無しでtitleを記事ごとに自由に設定する

HeadSpaceやAll in one SEOのようにtitleを操作できるプラグインはいれたくないし、カスタムフィールドも嫌、という方(がいるのか分かりませんが)は以下のようなコードをfunctions.phpに。

add_action('admin_menu', 'custom_title');
add_action('save_post', 'save_custom_title');
add_action('wp_head','insert_custom_title');
function custom_title() {
	add_meta_box('custom_title', 'title変更', 'custom_title_input_function', 'post', 'normal', 'high');
	add_meta_box('custom_title', 'title変更', 'custom_title_input_function', 'page', 'normal', 'high');
}
function custom_title_input_function() {
	global $post;
	echo '<input type="hidden" name="custom_title_input_hidden" id="custom_title_input_hidden" value="'.wp_create_nonce('custom-title-nonce').'" />';
	echo '<input type="text" name="custom_title_input" id="custom_title_input" style="width:100%;" value="'.get_post_meta($post->ID,'_custom_title',true).'" />';
}
function save_custom_title($post_id) {
	if (!wp_verify_nonce($_POST['custom_title_input_hidden'], 'custom-title-nonce')) return $post_id;
	if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return $post_id;
	$customTitle = $_POST['custom_title_input'];
	update_post_meta($post_id, '_custom_title', $customTitle);
}
function insert_custom_title() {
	if (have_posts()) : the_post();
	  $customTitle = get_post_meta(get_the_ID(), '_custom_title', true);
	  if ($customTitle) {
		echo "<title>$customTitle</title>";
      } else {
    	echo "<title>";
	      if (is_tag()) {
	         single_tag_title("Tag Archive for &quot;"); echo '&quot; - '; }
	      elseif (is_archive()) {
	         wp_title(''); echo ' Archive - '; }
	      elseif ((is_single()) || (is_page()) && (!(is_front_page())) ) {
	         wp_title(''); echo ' - '; }
	      if (is_home()) {
	         bloginfo('name'); echo ' - '; bloginfo('description'); }
	      else {
	          bloginfo('name'); }
	      if ($paged>1) {
	         echo ' - page '. $paged; }
        echo "</title>";
    }
    else :
      echo "<title>お探しのページはありません | サイト名</title>";
	endif;
	rewind_posts();
}

これで以下のようなtitle変更ボックスを加える事が出来ます。白紙の場合は「ページタイトル | サイト名」になります。

(via:Digging into WordPress

プラグイン

SEOに効果的っぽいプラグイン。沢山あるけどそんな要らないはずですので絞ってます。

  1. HeadSpace2 / 基本的になんでも出来ます
  2. WP Super Cache / キャッシュを作って表示を高速化します
  3. Yet Another Related Posts / GoogleのMatt推奨の関連ポストプラグイン
  4. WP-PageNavi / ページングはあったほうがいいです。僕はよくWP-AutoPagerize使います。
  5. Google XML Sitemaps / sitemap.xmlを生成します
  6. Redirection / リダイレクトを管理します
  7. WP Minify / jsやcssをまとめて軽量化します

人気のAll in One SEO Packも使いますけど僕は嫌いです。理由は無いです(キリッ

おまけ:高速化

重いお前のサイトどうにかしろって言われたらぐうの音も出ないんですが高速化もSEOとして効果あるので少しやっておきましょう。

  1. PunyPNG等を利用してパーツとして利用している画像のサイズを最適にする
  2. テンプレートタグが不要な箇所(例えばTOPページのURLとか)は直書きして負荷を減らす
  3. WP Super Cacheを使って静的にする
  4. WP Minify等を使用してjsやcssを最適化する
  5. .htaccessを利用する(WPサイト用の.htaccess例よりコードを引用※必ずリンク先で解説を御覧ください。)
    AddType image/x-icon .ico
     
    <IfModule mod_deflate.c>
    []SetOutputFilter DEFLATE
    BrowserMatch ^Mozilla/4 gzip-only-text/html
    BrowserMatch ^Mozilla/4\.0[678] no-gzip
    BrowserMatch \bMSI[E] !no-gzip !gzip-only-text/html
    SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|ico)$ no-gzip dont-vary
    SetEnvIfNoCase Request_URI _\.utxt$ no-gzip
    #DeflateCompressionLevel 4
    AddOutputFilterByType DEFLATE text/plain
    AddOutputFilterByType DEFLATE text/html
    AddOutputFilterByType DEFLATE text/xml
    AddOutputFilterByType DEFLATE text/css
    AddOutputFilterByType DEFLATE application/xhtml+xml
    AddOutputFilterByType DEFLATE application/xml
    AddOutputFilterByType DEFLATE application/rss+xml
    AddOutputFilterByType DEFLATE application/atom_xml
    AddOutputFilterByType DEFLATE application/x-javascript
    AddOutputFilterByType DEFLATE application/x-httpd-php
    </IfModule>
     
    <ifModule mod_expires.c>
    ExpiresActive On
    ExpiresDefault "access plus 1 seconds"
    ExpiresByType text/html "access plus 1 seconds"
    ExpiresByType image/gif "access plus 2592000 seconds"
    ExpiresByType image/jpeg "access plus 2592000 seconds"
    ExpiresByType image/png "access plus 2592000 seconds"
    ExpiresByType image/x-icon "access plus 2592000 seconds"
    ExpiresByType text/css "access plus 604800 seconds"
    ExpiresByType text/javascript "access plus 216000 seconds"
    ExpiresByType application/x-javascript "access plus 216000 seconds"
    ExpiresByType application/x-shockwave-flash "access plus 216000 seconds"
    </ifModule>
     
    FileETag none
     
    <FilesMatch "^(wp-config\.php|wp-mail\.php|install\.php|\.ht)">
    order allow,deny
    deny from all
    </FilesMatch>
     
    # BEGIN WordPress
    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !\.(xml|xsl|js|css|jpe?g|png|gif|ico)$
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
    </IfModule>
     
    # END WordPress
    

まぁでも基本的にはプラグインだけでも十分ですよね、というくらいプラグインが充実してますね。無理にハックする必要はないですけど覚えておけば便利ですし、知識も高まりますのでやっても損は無いかなと思います。