数年ぶりにWordpressのカスタムテーマを作る事になったので、
Underscores をベースにやっつけてみた。

Underscoresはフルカスタムしたいユーザー向けのスターターテーマで、Automatticが作ってるから超安心して使える。
必要環境とインストールについては丁寧に解説してくださってる記事があるのでそちらを参照頂くとして、
こちらではインストール完了後にした魔改造について適当にメモっていくつもりです。
長くなりそうなので改造個所毎に記事分けます。

インストール後のディレクトリ構造

手順通りにインストールを終えるとこんな具合になります。

underscores インストール後のディレクトリ構造

見慣れないファイルをざっくり紹介。

  • assets – 自分で作れと言われるディレクトリ
  • Gruntfile.js – gruntの設定とかするファイル。削除したらダメ
  • layouts – サンプルのレイアウト用CSSが入っている
  • node_modules – ローカル用のnodeモジュールが入っている。削除したらダメ
  • package.json – npmの設定ファイル。削除したらダメ

Sass+Compassを入れる

プリプロセッサが無いなんて耐えられない/(^o^)\
LessでもStylusでもそう手順は変わらないと思うので何を使うかはお好みで。

Grunt用のgrunt-contrib-compassを入れます。
こいつはSassとCompassがインストールされていることが前提になるので、まだ入ってなければ先にオリジナルのSassとCompassをインストールしておく。

Underscoresインストール時と同じくテーマディレクトリのルートでコマンドを叩くと、

$ npm install grunt-contrib-compass --save-dev

(Sassだけでいいならgrunt-contrib-sassにする)

つらつら〜っとログが流れてインストールがつつがなく終わります。

Sassのファイルを入れるディレクトリを用意する。

underscores-wp_2
assets/scssにしました。

ルートにある元のstyle.cssをstyle_original.cssに名前変更しておく。
assets/css/srcは使わないので消す。

underscores-wp_3

Gruntfile.jsの編集

エディタでGruntfile.jsを開く。

開いたら適当な場所にCompass使います宣言を追加する。

	
	// Load other tasks
	grunt.loadNpmTasks('grunt-contrib-jshint');
	grunt.loadNpmTasks('grunt-contrib-concat');
	grunt.loadNpmTasks('grunt-contrib-uglify');
	grunt.loadNpmTasks('grunt-contrib-cssmin');
	grunt.loadNpmTasks('grunt-contrib-watch');

	grunt.loadNpmTasks('grunt-contrib-compass'); // ←これ

grunt.initConfig( {以下にUnderscoresが生成してくれたデフォルトのオプションが入ってますが、
そこにCompassのオプションを追加する。

compass: {
  dist: {
	 options: {
	  sassDir: 'assets/scss',
	  cssDir: './',
	  environment: 'production',
	  outputStyle: 'compressed'
	}
  }
},

assets/scssにstyle.scssを作る。

underscores-wp_4

コマンド叩く

$ grunt comapss

underscores-wp_5

ルートにstyle.cssが出来たらインストール完了。

テーマコメント挿入

style.cssにはWordpressのテーマと認識させるためのコメントが必要なので、コンパイルされる時に勝手に入れるようにしておく。

名前を変えておいたstyle_original.cssを開いて先頭のブロックコメントをコピーしたら、
Compassタスクのオプションにコピペして、bannerオプションとして動作するよう編集する。

compass: {
  dist: {
	 options: {
		banner: '/*\n' +
		 '* Theme Name:  My Theme\n' +
		 '* Theme URI:   http://wordpress.org/themes\n' +
		 '* Description: The best WordPress theme ever made!\n' +
		 '* Author:      Tenderfeel\n' +
		 '* Author URI:  \n' +
		 '* Version:     0.1.0\n' +
		 '* Tags:\n' +
		 '*\n' +
		 '* License:     GPLv2+\n' +
		 '* License URI: http://www.gnu.org/licenses/gpl-2.0.html\n' +
		 '*\n' +
		 '* Resetting and rebuilding styles have been helped along thanks to the fine work of\n' +
		 '* Eric Meyer http://meyerweb.com/eric/tools/css/reset/index.html\n' +
		 '* along with Nicolas Gallagher and Jonathan Neal http://necolas.github.com/normalize.css/\n' +
		 '* and Blueprint http://www.blueprintcss.org/\n' +
		 '*/\n',
	  sassDir: 'assets/scss',
	  cssDir: './',
	  environment: 'production',
	  outputStyle: 'compressed',
	  specify: ['assets/scss/style.scss']
	}
  }
},

bannerオプションはspecifyオプションとセットでないと動かんので、specifyにstyle.scssを追加しておく。
テンプレートタグを使ってpackage.jsonの値を流用すると便利だと思う。

		banner: '/*\n' +
		 '* Theme Name: <%= pkg.title %>\n' +
		 '* Theme URI:  http://wordpress.org/themes\n' +
		 '* Description: <%= pkg.description %>\n' +
		 '* Author:  <%= pkg.author.name %>\n' +
		 '* Author URI:  \n' +
		 '* Version:  <%= pkg.version %>\n' +
		 '* Tags:\n' +
		 '*\n' +
		 '* License:     GPLv2+\n' +
		 '* License URI: http://www.gnu.org/licenses/gpl-2.0.html\n' +
		 '*\n' +
		 '* Resetting and rebuilding styles have been helped along thanks to the fine work of\n' +
		 '* Eric Meyer http://meyerweb.com/eric/tools/css/reset/index.html\n' +
		 '* along with Nicolas Gallagher and Jonathan Neal http://necolas.github.com/normalize.css/\n' +
		 '* and Blueprint http://www.blueprintcss.org/\n' +
		 '*/\n',

もう一度コマンドを叩けばコメントが追加される。

compassのオプションでcompressedを設定していたら圧縮は不要なので、Gruntfile.jsのcssminタスクは消した。

style.css以外のcssファイルが作りたくなったら

作りたいファイルに応じた設定を増やせばおk。

compass: {
  style: {
	 options: {
		banner: '/*\n' +
		 '* Theme Name: <%= pkg.title %>\n' +
		 '* Theme URI:  http://wordpress.org/themes\n' +
		 '* Description: <%= pkg.description %>\n' +
		 '* Author:  <%= pkg.author.name %>\n' +
		 '* Author URI:  \n' +
		 '* Version:  <%= pkg.version %>\n' +
		 '* Tags:\n' +
		 '*\n' +
		 '* License:     GPLv2+\n' +
		 '* License URI: http://www.gnu.org/licenses/gpl-2.0.html\n' +
		 '*\n' +
		 '* Resetting and rebuilding styles have been helped along thanks to the fine work of\n' +
		 '* Eric Meyer http://meyerweb.com/eric/tools/css/reset/index.html\n' +
		 '* along with Nicolas Gallagher and Jonathan Neal http://necolas.github.com/normalize.css/\n' +
		 '* and Blueprint http://www.blueprintcss.org/\n' +
		 '*/\n',
	  sassDir: 'assets/scss',
	  cssDir: './',
	  environment: 'production',
	  outputStyle: 'compressed',
	  specify: ['assets/scss/style.scss']
	}
  },
  others: {
	 options: {
	  sassDir: 'assets/scss',
	  cssDir: 'assets/css',
	  environment: 'production',
	  outputStyle: 'compressed',
	  specify: ['assets/scss/custom.scss']
	}
  }
},

othersの設定でassets/scss/custom.scssをassets/css/custom.cssに生成するよう指定した。
bannersオプションは入れてないので、custom.cssにはテーマコメントは入らない。

watch対象にする

ファイルに修正があったら勝手にコンパイルさせる。
これは元からあるwatchタスク内のstyles以下を改変すればおk。

styles: {
	files: ['assets/scss/*.scss'],
	tasks: ['compass'],
	options: {
		debounceDelay: 500
	}
},

コマンド叩いてwaiting…と表示されたら

$ grunt watch

ファイルの編集で勝手にコンパイルしてくれるようになる。

underscores-wp_6

ヘッダーの追加

素の状態だとheader.phpがDOCTYPE宣言しかなくてCSSすら読み込まれないので、適当に追加する。

<?php
/**
 * The template for displaying the header.
 *
 * @package My Theme
 * @since 0.1.0
 */
 ?><!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
	<meta charset="<?php bloginfo( 'charset' ); ?>">
	<meta name="viewport" content="width=device-width">
	<title><?php wp_title( '|', true, 'right' ); ?></title>
	<link rel="profile" href="http://gmpg.org/xfn/11">
	<link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>">
	<?php wp_head(); ?>
</head>

functions.phpの編集

wp_head関数でcssとかが読み込まれるようになると、デフォルトで設定されているcssやjsを読み込むタグがhead内に追加される。
不要なものがあればfunctions.php 119行目くらいにあるscripts()関数を編集する。

/**
 * Enqueue scripts and styles
 */
function my_scripts() {
	wp_enqueue_style( 'style', get_stylesheet_uri() );

	wp_enqueue_script( 'small-menu', get_template_directory_uri() . '/js/small-menu.js', array( 'jquery' ), '20120206', true );

	if ( is_singular() && comments_open() && get_option( 'thread_comments' ) ) {
		wp_enqueue_script( 'comment-reply' );
	}

	if ( is_singular() && wp_attachment_is_image() ) {
		wp_enqueue_script( 'keyboard-image-navigation', get_template_directory_uri() . '/js/keyboard-image-navigation.js', array( 'jquery' ), '20120202' );
	}
	
	$postfix = ( defined( 'SCRIPT_DEBUG' ) && true === SCRIPT_DEBUG ) ? '' : '.min';
        //uglifyで圧縮したjsを読み込む
	wp_enqueue_script( 'my', get_template_directory_uri() . "/assets/js/my-theme{$postfix}.js", array(), MY_VERSION, true );
	//cssminで圧縮したcssを読み込む	
	wp_enqueue_style( 'my', get_template_directory_uri() . "/assets/css/my-theme{$postfix}.css", array(), MY_VERSION );
}