作成者別アーカイブ: ニタ

ニタ について

PHP、javascriptがメインですが、他の言語も触ったり触られたり。 WordPressが好きで、プラグインなども公開しています。 http://dev.blog.fairway.ne.jp/wordpress-plugin-rucy/

Vimって☆Emmetさん

タグ: , | 投稿日: 投稿者:

どうも、ニタです。先日、社内でEmmet(Zen Conding)を紹介する機会がありました。
当日は、IDEやテキストエディタのアプリ上でデモを行ったのですが、vimmerが多いせいか、そもそもHTMLコーディングをする機会が少ないのか、あまり採用されてない感じです(´・ω・`)
そこで今回は、vimでEmmetを使えるようにしてみます。

Emmetって何?

Emmetは、HTMLやCSSのコーディングを効率化してくれるツールです。
テキストエディタやIDE上でショートカットコードを打つと、HTMLやCSSに転換されます。

Emmet

Zen Codingというのもあります

Emmentで検索すると「Zen Coding」というのも出てきます。これはEmmetの前身となるプロジェクトで、EmmetはZen Codingを基に作られており、Zen Codingの改良版と言って良いでしょう。

閑話休題。実際にEmmetを使ってみましょう。

html:5

Emmetのプラグインが入ったエディター上で、こんな感じに入力して展開させると…

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    
</body>
</html>

こんな感じに一気にHTMLコードができちゃう!
更に…

(div#content-id$$$.page-content-class>h1+h2)*2

独自記法を使ってタグのidやクラスを指定したり、同じ要素をくり返したりも出来ます。

<div id="content-id001" class="page-content-class">
    <h1></h1>
    <h2></h2>
</div>
<div id="content-id002" class="page-content-class">
    <h1></h1>
    <h2></h2>
</div>

繰り返しはループ処理でも書ける場合もありますが、コーディングの高速化と閉じタグや属性を書く手間を最小限に抑えられるのが気に入っています。

VimでEmmetを使えるようにする

さていよいよ本題。
VimでEmmetを使えるようにするには「emmet-vim」というプラグインをインストールします。
このプラグインは、Vimのプラグイン管理ツールのNeoBundleで管理します。NeoBundleに関しては、後日改めて紹介するかもしれません。
取り急ぎ、以下の様にしてNeoBundleとemmet-vimをインストールします。

NeoBunbleとemmet-vimのインストール

NeoBundleは以下のように

# 配置先のディレクトリを作成する
mkdir -p ~/.vim/bundle
cd ~/.vim/bundle

# NeoBundleをgitHubのリポジトリから取得する
git clone git://github.com/Shougo/neobundle.vim

# emmet-vimをgitHubのリポジトリから取得する
git clone https://github.com/mattn/emmet-vim.git 

その後、vimの設定ファイル~/.vimrcを作成してNeoBundleをインストールします。

set nocompatible
filetype plugin indent off

if has('vim_starting')
  set runtimepath+=~/.vim/bundle/neobundle.vim
  call neobundle#rc(expand('~/.vim/bundle'))
endif 

NeoBundleFetch 'Shougo/neobundle.vim'

# 以下は必要に応じて追加
NeoBundle 'Shougo/unite.vim'
NeoBundle 'Shougo/neosnippet.vim'

filetype plugin indent on

また、Mac OSX El Capitanの場合、上記の設定だとインストールできないようです。

# インストール用シェルファイルをダウンロードし、実行
$ curl https://raw.githubusercontent.com/Shougo/neobundle.vim/master/bin/install.sh > install.sh
$ sh ./install.sh

.vimrcの表記も変わります。

" Note: Skip initialization for vim-tiny or vim-small.
 if 0 | endif

 if has('vim_starting')
   if &compatible
     set nocompatible               " Be iMproved
   endif

   " Required:
   set runtimepath+=~/.vim/bundle/neobundle.vim/
 endif

 " Required:
 call neobundle#begin(expand('~/.vim/bundle/'))

 " Let NeoBundle manage NeoBundle
 " Required:
 NeoBundleFetch 'Shougo/neobundle.vim'

 " My Bundles here:
 " Refer to |:NeoBundle-examples|.
 " Note: You don't set neobundle setting in .gvimrc!

 call neobundle#end()

 " Required:
 filetype plugin indent on

 " If there are uninstalled bundles found on startup,
 " this will conveniently prompt you to install them.
 NeoBundleCheck
NeoBundle 'mattn/emmet-vim'

上記を~/.vimrcに追記し、vim上で:NeoBundleInstallというコマンドを実行してプラグインをインストールします。

VimでEmmetしてみる

Vim上でEmmetを実行するには、<C-y>,で行います。control + yのあとカンマ「,」をタイプします。
キーバインドの設定は~/.vimrcで設定します。

# 実行時のキーバインド変更する場合(ここではYからEに変更)
let g:user_emmet_leader_key = '<C-E>'

これでVim上でも高速HTMLコーディングが可能になりました。

それではまた来年!


[WordPress]WordCampTokyo2015に行ってきたよ

タグ: | 投稿日: 投稿者:

どうも、ニタです。

先日、WordPressの交流会WordCamp Tokyo 2015に参加してきました。
WordCamp Tokyo 2015

wctokyo_2015-10-31 10 42 47

このところ、WordPress関連のことしか書いていませんが、WordPressが好きすぎるので良いかなと勝手に思ってます。

今年のWordCamp Tokyoのテーマが「More Publishing」ということで、WordPressのテーマやプラグインに関するセッションやワークショップの他に、サイト運営者やブロガーといった、「情報発信」を行う方を対象にしたセッションも多く見られました。

今回は、私が参加したセッションの中で、興味深かったセッションの感想など書いていこうと思います。

【基調講演】「なんとなく」の壁を越えよう!自信を持って WordPress を選択するためのヒント

 

WordPressの運営会社Automattic社に所属の数少ない日本人スタッフ、高野直子さんによる基調講演。

  • Web全体の24.8%のWebサイトがWordPressで作られていること
  • 数あるCMSの中でもWordPressが利用率58.8%と圧倒的なシェアを誇っていること
  • TimeやTHE NEW YORKER、TOYOTA ブラジルといった大規模サイトから男木島図書館のサイトといった小規模サイトもWordPressで作られている

Webサイトを立ち上げるにあたり、ベースシステムにWordPressを選択するいくつかの根拠として、上記のことなどを説明していました。
WordPressが素早いWebサイト構築に向いていて、カスタマイズしやすいからこその、WordPressの利用率なのかもしれません。

また、年内リリースが予定されている次期バージョン、WordPress 4.4の特徴も紹介していました。
私が気になったものは、以下のもの。

WP REST API

REST API経由で外部から記事の取得や、記事の更新などが出来るようになります。
外部サイトやアプリから記事の取得更新が可能になり、情報発信の頻度、速度の向上が見込まれます。

このAPIを使用したアプリやWebサービスの開発をするのも面白いかもしれません。

Responsive Images

HTML5のsrcset属性を利用した、画面やウィンドウサイズなどのユーザーの端末環境に最適な解像度の画像を配信するのが、Responsive Imagesです。

これは、RICG Responsive Imagesというプラグインがコアに統合された形になります。通常通り画像をアップロードすれば、自動的にsrcset属性が追加され適宜画像が指定されるようになるようです。

スマホやタブレット端末、高解像度モニタなどユーザー環境が多様化し、画像サイズ指定に悩まされていた方も多いと思いますが、Responsive Imagesはその解決策の一つだと思います。

embed(記事の埋め込み)

Twitterのツイートや、はてなブログのブログカードのようにWordPressの記事を外部サイトに埋め込む事ができます。
参照リンクや引用文をただのテキストではない見せ方をすることで、記事の見栄えが良くなったり、情報発信の楽しさが増えるのではないでしょうか。

ただし、SSLサイトで非SSLサイトのコンテンツを埋め込むことは出来ないようです。(機能としてNGな訳ではなく、ブラウザ側でブロックされるでしょう)

Content Publishing in 2016

Human Made社のNoel Tockさんによる、情報発信の形の変化や対応策についてのセッション。
Noelさんは、レストランサイトを構築できるWebサービスhappytablesなどを数多くのサイトをプロデュースしています。

記事を公開し自分のWebサイトへユーザーを誘導するのに、従来のSNSや外部サービスの利用だけでは、今後誘導し難くなるとされています。
スマホやタブレット端末の普及に伴い、Webサイトの他にアプリやWebサービスも数多く公開されていますが、それらを利用するユーザーの所有時間は1日24時間と変わりません。
そういった限られた状況において、いかに自分のWebサイトやコンテンツを見てもらう時間をユーザーから取れるのかが重要になってきます。

海外の有名サイトの情報発信方法を参考に、ユーザーの環境に寄り添った、自分のコンテンツに適した情報発信方法をいくつか紹介していました。

WordPressで行う継続的インテグレーション 入門編  -プラグイン開発・保守地獄から学んだこと-

Custom Post Type Permalinksなど有名プラグインを多く開発しているToro_Unitこと占部さんのセッション。

 

ざっくり要約すると、「PHP Unit使ってテスト駆動開発しないと地獄見るぜ」。
WordPressには「WP_UnitCase Class」というPHP Unitを継承したテスト用クラスも用意されているから、プラグイン開発するなら使ってみれば良いじゃない。ということでした。

WordPressをCUIでコントロールできる「WP_CLI」にある、プラグイン作成コマンドにも標準でテストコードやTravis CI用のymlファイルが生成されるので、テストコードを書いて損はないと思います。

ホント、テストは大事ですよ…

※「WP_CLI」はVagrantで構築できるWordPress開発環境の「VCCW」にも入っているので、WordPressサイトやプラグイン開発は、VCCWを使うのをマジお薦めします。

The Best Practices of Making WordPress Site Multilingual

多言語サイトをWordPressで構築する際のいくつかの方法について。

 

スライドにあるような、WordPressのマルチサイト機能や多言語対応プラグインなどの紹介がありました。
なかでも「YarakuZen」という翻訳サービス(商用有料)が気になりました。
すでにプラグイン化されているので、今度試してみたいと思います。

Webサイトをめぐるセキュリティ状況と効果的な防御方法~WordPressを題材として~

セキュリティと言ったらこの方、徳丸さんのセッションはWordCampでも人気のセッションだったと思います。
WordPressがカスタマイズしやすいCMSだからこそセキュリティにはコストを掛けるべきではないでしょうか。
自分でカスタマイズしたことで、セキュリティホールを自ら開けてしまうケースもあれば、セキュリティを考慮せず作られたプラグインを使っている場合もあります。
WordPressではセキュリティを高めるプラグインも多く公開されているので、それらを使ったセキュリティ対策も一つの手かと思います。

ライターと制作者のメディアの作り方

セッションタイトル通りですが、ライター、制作者の立場から、WordPressサイトでのサイト設計、コンテンツ設計についてディスカッションが行われました。
登壇されたのは、LIGブログの元編集長、コンテンツ制作会社ノオトでライターをしている朽木 誠一郎さんと、フリーランスWebデザイナーのおおはらかずきさん。

おおはらかずきさんが運営しているブログサイトは、225記事で月間100万PVを稼いでいる人気サイトです。

私は最近、当社コーポレートサイトにてFAIRWAY NEWSを運営しているので、記事を制作する上でのコツを多く聞けて有意義なセッションでした。

まとめ

wctokyo_2015-10-31 22 34 48

WordPressは他のCMSと比較してもカスタマイズしやすいCMSだと思います。
それ故に開発者だけでなく、デザイナーやブロガーなどのコンテンツ制作者など多くの人に利用されているCMSだと今回のWordCampに参加し改めて感じました。
様々な使い方が出来、テーマやプラグインが利用できる反面、セキュリティを万全にしなければならないし、情報発信方法、ユーザーに知ってもらう手段なども時代に合わせて変えていかなければいけません。

基本的なことですが、サイト構築、コンテンツ制作の上で大事にしなければならないことだと思いました。
それではまた。

追伸

先月拙作のWordPressプラグインをアップデートしました。
新機能として「ロールバック機能」を追加しています。
これは一度予約更新で更新した投稿内容を、日時指定で更新前の状態に戻すことができます。
予約更新する投稿内容を期間限定で表示させる場合などに使えると思います。


[WordPress]需要度低めだけど意外と助かるカスタマイズ3選

タグ: , | 投稿日: 投稿者:

こんにちは、ニタです。
WordPressを利用したWebサイトを開発する際、既存テーマファイルをカスタマイズしたり、プラグインをインストールしていきます。
それでも対応できないものは、使用するテーマファイル内のfunctions.phpにコードを記述するなどして対応していきます。
今回は、その中でも需要度低めな?カスタマイズ方法をいくつかご紹介します。

generatorのmetaタグを削除

WordPressでは、headタグ内にgeneratorのmetaタグが挿入されます。
これはページ作成ツールの情報なのですが、あまり必要性がないのと、セキュリティ面を考慮しても削除したほうが良いです。
※バージョンを外部に晒すことになるので、WordPressをアップデートしていない場合、攻撃対象になるため。

利用中のテーマファイルにある、functions.phpに以下を追記すると、generatorのmetaタグが作成されません。

if(has_action('wp_head','wp_generator')) {
    remove_action( 'wp_head', 'wp_generator' );
}

これだけでもページのソース上からは削除されますが、同時に生成されるRSSフィードなどにも生成ツール情報が書き込まれるので、そちらも削除します。

$actions = array( 'rss2_head', 'commentsrss2_head', 'rss_head', 'rdf_header',
'atom_head', 'comments_atom_head', 'opml_head', 'app_head' );
    
foreach ( $actions as $action ) {
    if ( has_action( $action, 'the_generator' ) ) {
        remove_action( $action, 'the_generator' );
    }
}

WordPressからのメール送信でSMTPを利用する

WordPressには、wp_mailというphpmailerを使用したメール送信関数がデフォルトで備わっています。

関数リファレンス/wp mail – WordPress Codex 日本語版

サイトポリシー上、SMTPを利用してメール送信する場合は、phpmailerの設定処理をカスタマイズして対応します。
こちらも、functions.phpに記述します。
send_smtp_emailという関数名は適宜変更しても構いません。

add_action('phpmailer_init','send_smtp_email');
function send_smtp_email( $phpmailer )
{
    // SMTP有効設定
    $phpmailer->isSMTP();

    // メールサーバーのホスト名
    $phpmailer->Host = "使用するSMTPサーバ名";

    // SMTP認証の有無(true か false)
    $phpmailer->SMTPAuth = true;

    // SMTPポート番号(25,465,587など適宜) 
    $phpmailer->Port = "587";

    // SMTP認証時のユーザー名
    $phpmailer->Username = "ユーザー名";

    // ユーザーのパスワード
    $phpmailer->Password = "パスワード";

    // SMTP暗号化方式(tls か ssl)
    $phpmailer->SMTPSecure = "tls";

    // 送信者メールアドレス
    $phpmailer->From = "test@example.com";
    
    // 送信者名
    $phpmailer->FromName = "送信者名";
}

テーマ内でセッションを使う

基本的にWordPressのフロント側では、PHPのセッションは使用していません。
ページによってはセッションを利用したページ処理があると思います。
セッションを使う場合はこんな感じでfunctions.phpに記述します。
common_session_startという関数名は適宜変更しても構いません。

add_action('init', 'common_session_start');
function common_session_start(){
    if(!isset($_SESSION)){
        session_start();
    }
}

いかがでしたでしょうか。
ちょっとニッチなカスタマイズでしたが、ご利用いただければと思います。
それでは。


[WordPress]A/Bテスト用プラグイン「MaxA/B」

タグ: | 投稿日: 投稿者:

最近「痩せた?」と聞かれるようになりました。
糖質制限ダイエットはすごいですね。決して仕事が原因じゃないです。こんにちは、ニタです。

Webサイトのデザイン、レイアウト、文言、機能などを最適化するために、A/Bテストで効果を測る場合があります。
A/Bテストとはざっくり言いますと、用意された複数のバージョンのページ(バージョンA、B)にアクセスしたユーザをランダムに振り分けて、ユーザの反応(目標となる成果が得られるか)を計測するテストのことです。

今回は、WordPressで構築したWebサイトでのA/Bテストの設定、実施方法を解説します。
※ここでは、テスト対象ページ「バージョンA」と、別バージョン「バージョンB」を比較調査するテストの設定を説明します。

「MaxA/B」を使ったテスト設定

WordPressでのA/Bテストは「MaxA/B」というプラグインを使用します。
MaxA/B
「MaxA/B」を使うと、指定された固定ページでのA/Bテストが可能になります。

また、既存の投稿・固定ページを複製するプラグイン「Duplicate Post」を使用することで、効率よくテストページ作成ができるので、こちらもインストールします。
Duplicate Post

各プラグインインストール方法

各プラグインは以下の手順でインストールします。

  • WordPress管理画面「プラグイン」 > 「新規追加」に移動
  • 「Duplicate Post」の場合、検索のテキストフォームで「duplicate post」を検索
  • 「MaxA/B」の場合、検索のテキストフォームで「maxab」を検索
  • 各プラグインが表示されるので、「今すぐインストール」ボタンからインストール開始
  • インストールが成功したら、プラグインを有効化する

テスト対象の固定ページを複製、編集

テスト対象ページ「バージョンA」を複製し、別バージョン「バージョンB」のページを作成します。
「Duplicate Post」をインストール、有効化すると、固定ページ一覧のテスト対象ページに「複製」というメニューが増えるので、そちらからページを複製します。

img_maxab_004

複製が完了すると、「下書き」状態で複製されます。
複製先を「バージョンB」としてタイトル、スラッグ、記事内容を適宜編集し、ページを公開します。

A/Bテストのテスト設定

つづいて、MaxA/Bでテスト設定を登録します。MaxA/Bの設定画面に移動し「Add New」ボタンから、テストを追加します。
img_maxab_005

img_maxab_001

新規テスト設定画面が表示されるので、各項目を選択、設定し「Create」ボタンでテストを作成します。
各項目の内容は以下のとおりです。

項目名 設定内容
Name テスト名称
Original page テスト対象のオリジナルページ。公開中の固定ページから選択する。
ページ選択すると、ページURLが表示される。
Variation page 1 テスト対象ページの別バージョンのページ。固定ページから選択。
Variation page 2 別バージョンページ2番目。バージョンが複数ある場合、選択する。
Variation page 3 別バージョンページの3番目。
The conversion page 目標ページ。テスト対象ページから遷移し最終的に成果が得られるページ。
問い合わせページの問い合わせ完了ページなど。
"Is on another site somewhere else (enter URL)"を選択すると外部URLを入力指定できる。外部URLを選択すると、登録後外部URLのページに追記するスクリプトが表示される。
Experiment ends when テスト終了のタイミング。
・It is manually stopped:手動停止
・Total traffic reaches:合計アクセス数(指定)
・Each page reaches at least:ページ毎のアクセス数(指定)

今回はテスト対象ページと別バージョン1ページ、目標ページを設定し、手動停止でテスト登録します。
登録後、テストが開始されます。

スクリプトの設置

目標ページを外部URLに設定した場合、テスト登録後、目標ページに追記するJavaScriptが表示されます。

img_maxab_002

目標ページ(外部URL)のheadの閉じタグの直前に追記するコードが表示されます。

テストの状況確認

テスト登録後、テストは即時開始されるので、実際にテスト対象ページにアクセスしてみます。
テスト対象ページと別バージョンページへの振り分けはセッションに登録されるので、セッション登録されないChromeのシークレットウィンドウやFirefoxのプライベートウィンドウでアクセスすると分かりやすいです。

ページの振り分けの確認をし、目標ページまで遷移したら、MaxA/Bの設定画面を確認します。

img_maxab_003

各バージョンへのアクセス率、目標ページへの到達率が表示され、どのバージョンのページが効果的かが分かるようになっています。
また、実施中のテストを中止したり終了のタイミングを変更するには、詳細画面から編集ができます。

img_maxab_006

今回紹介したプラグインでのA/Bテストの他に、GoogleAnalyticsにある「ウェブテスト」というA/Bテスト計測も同時に行うことで、より詳細なテスト結果が得られます。
GoogleAnalyticsの設定方法などは、後日改めて説明したいと思います。
それでは、良いテストライフを。


Analytics APIとRaspberry Piでサイトのアクセス状況を可視化するテスト

タグ: , | 投稿日: 投稿者:

こんにちは、ニタです。

最近私のMacBookProでは、GoogleAnalyticsのリアルタイムのアクティブユーザー数を常に表示させ、Webサイトのアクセス状況をすぐ確認できるようにしています。

このアクセス状況を、モニタ上だけではなく他の方法で可視化できないか現在検討しています。
そこで今回は、手頃なRaspberry Piを使ってテストモデルを作ってみました。

※記事内のRaspberry PiはRaspbianをインストール済みの「Raspberry Pi 2 Model B」を使用しています。

LチキじゃないですLチカです

Lチキは某コンビニのチキンです。ファ◯マの方が私は好きです。
今回初めてRaspberry Piを触るので、手始めとして電子工作系の「Hello World」、Lチカをやってみます。
「Lチカ」とは、「LEDをチカチカ点灯させる」ことの略称です。「Raspberry Pi Lチカ」とか「Arduino Lチカ」で検索すると、世界中の方々のLEDをチカチカさせた記事が出てきますのでそちらを参考に組み込みます。

img_nita_lchika010
img_nita_lchika011

PHPでGPIOを操作する

今回はPHPからGPIO(汎用入出力)の操作、AnalyticsAPIの利用を行うので、Raspbianにphpをインストールします。

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install php5

PHPによるGPIOの操作には、php-gpioを使用します。
composerからのインストールが推奨されているので、素直にそうします。

wget http://getcomposer.org/composer.phar
php composer.phar create-project --stability='dev' ronanguilloux/php-gpio l-chika

l-chikaというディレクトリにphp-gpioのパッケージがインストールされたので、GPIO操作のコードを書きます。

cd l-chika
vim test.php 


<?php 
require 'vendor/autoload.php';

use PhpGpio\Gpio;

// GPIOの5番を使用
$pin = 5;
$gpio = new GPIO();
$gpio->setup($pin, "out");

// GPIO5番に繋いだLEDを10回点灯させる
for($i = 0; $i < 10; $i++){
    $gpio->output($pin, 1);
    sleep(2);

    $gpio->output($pin, 0);
    sleep(1);
}
$gpio->unexportAll();

こちらをsudo php test.phpと言った感じで実行すると、LEDが点滅します。
GPIOのピン番号を指定し、$gpio->output()で制御する感じですね。

img_nita_lchika012

Analytics APIの設定

さて、続いてはAnalyticsのアクティブユーザー数を取得するコードを書いていきます。
アクティブユーザー数を取得するためには、Google Analytics APIを使用します。

プロジェクトの作成

Google Developers Consoleにて、プロジェクトを作成します。

img_nita_lchika001
img_nita_lchika002

作成したプロジェクトで利用できるAPIに「Analytics API」を追加します。

「APIと認証」→「API」と進み、Analytics APIを選択し、有効にします。

img_nita_lchika003
img_nita_lchika004

API有効化後、「APIと認証」→「認証情報」に移動しクライアントIDから認証情報を作成します。
この認証情報を使用してAPIを利用できるようになります。

img_nita_lchika005

クライアントIDを作成すると、次のウィンドウが表示されるので、「サービスアカウント」を選択します。

img_nita_lchika006

認証情報画面が表示されると、.jsonファイルがダウンロードされますが、今回は使用しません。
今回は*.P12ファイルをしようするので、.P12ファイルをダウンロードします。
また、認証情報画面の「クライアントID」「メールアドレス」は今後使用するので、控えておいてください。

img_nita_lchika007

Google Analyticsにユーザーを追加

アクティブユーザー数を確認したいサイトのGoogle Analyticsの設定画面で、APIがAnalyticsビューを利用できるよう、権限を与えます。

img_nita_lchika008

また、AnalyticsのビューIDを控えておきます。

img_nita_lchika009

Google API Clientのライブラリをインストール

PHPからAPIを利用するよう、クライアントライブラリをインストールします。
ComposerかGitHubからインストールできます。
今回はComposerからインストールします。

参考:API Client Library for PHP

php-gpioで作成したcomposer.jsonにAPI Clientのパッケージを追記します。

# composer.jsonに以下を追記。

"require": {
  "google/apiclient": "1.0.*@beta"
}

# 追記後、composerを更新
php composer.phar install
php composer.phar update

AnalyticsAPIからのリクエスト結果をLチカへ

Google Client APIのパッケージがインストールされたので、アクティブユーザー数を取得し、ユーザー数分Lチカさせるプログラムを作成します。

<?php
set_include_path("./vendor/google/apiclient/src/" . PATH_SEPARATOR . get_include_path());
 
require_once 'Google/Client.php';
require_once 'Google/Service/Analytics.php';
require 'vendor/autoload.php';

use PhpGpio\Gpio;
    
// サービスアカウント名(メールアドレス)
$service_account_name = 'YOUR_MAIL_ADDRESS@developer.gserviceaccount.com';
// P12キーファイルのパス
$key_file_location = './YOUR_KEY_FILE.p12';
// アナリティクスのビューID
$analytics_view_id = 'ga:1234567';
 
session_start();
 
if ( !strlen($service_account_name)
    || !strlen($key_file_location)) {
  echo missingServiceAccountDetailsWarning();
}
 
$client = new Google_Client();
 
if (isset($_SESSION['service_token'])) {
  $client->setAccessToken($_SESSION['service_token']);
}
 
$key = file_get_contents($key_file_location);
$cred = new Google_Auth_AssertionCredentials(
    $service_account_name,
    array('https://www.googleapis.com/auth/analytics'),
    $key
);
$client->setAssertionCredentials($cred);
 
if($client->getAuth()->isAccessTokenExpired()) {
  $client->getAuth()->refreshTokenWithAssertion($cred);
}
 
$_SESSION['service_token'] = $client->getAccessToken();
 
// アナリティクスクライアントを生成
$analytics = new Google_Service_Analytics($client);
 
try {
    // リアルタイムデータを取得する
    $results = $analytics->data_realtime->get(
            $analytics_view_id,
            'rt:activeUsers'
    );
 
    // 取得結果からリアルタイムアクティブユーザ数を取り出す
    $totals = $results->getTotalsForAllResults();
    $res = $totals["rt:activeUsers"];
    
    if($res == 0){
    echo "no active user.".PHP_EOL;
        exit;
    }
    
    
    // アクティブユーザー数分Lチカする。    
    $pin = 5;
    $gpio = new GPIO();
    $gpio->setup($pin, "out");
    
for($i = 0; $i < $res; $i++){
    $gpio->output($pin, 1);
    sleep(2);

    $gpio->output($pin, 0);
    sleep(1);
}
$gpio->unexportAll();
     
} catch (apiServiceException $e) {
    echo $e->getMessage();
}

このプログラムをcronで定期実行させると良いでしょう。
このAnalytics APIは、無料枠でのリクエスト上限が50,000リクエスト/日になっているので、1サイトのみであれば、5分間隔での実行でも十分かと思います。

今後の予定

今回はプロトタイプとしてLチカさせるだけになりましたが、
今後は、これを基に何かモノを動かしたりして、アクセス状況を分かりやすくしていきたいと思います。
それでは、また。


WordPressでajaxを使う

タグ: , , | 投稿日: 投稿者:

こんにちは、ニタです。

早速ですが、WordPressのプラグインを更新しました!

アイキャッチ画像と更新日を予約更新対象に追加しました!
iframeタグが消えたり、brタグなどに追記したstyle定義も消えないようにしました!
予約更新内容でのプレビュー機能はもう少し先になりそうです!

どうぞよろしくお願いします!
See you again next time, Enjoy WordPress Life!!

と、

これでおしまいとは、いきませんよねぇ…。
では、改めて。

WordPressでもajaxをカンタンに使いたい

WordPressのテーマやプラグインを開発していると、投稿データや外部からのデータをスムーズに取得したい時があります。なるべくスマートに。ajaxとかで。
例えば、投稿一覧ページをページングからajax読み込みによる無限スクロールにしてみたり、プラグインで下のような読み込み機能に使ってみたり…

多少コツが要ります

しかし、WordPressのフロント側のルーティングはすべてコンテンツページとして表示されるので、ajax用のJSONを返すページ(エンドポイント)を作り、そこへPOSTかGETでアクセスさせればajax通信できるわけではありません。
ですが、WordPressの管理画面はajaxをバッキバキにキメていて、そのための機能が用意されておりますので、そちらを使ってajax通信を行います。

基本的な実装の流れはこんな感じです。

  1. wp_ajax_ホニャララというアクションフックを追加し、そのアクションフックに関数を登録。
  2. POSTかGETでのリクエストを受け取って、求めているデータをJSON形式で返却する関数(アクションフックに登録する関数)を作成。
  3. データ取得用のJavaScriptの作成。

実際に作ってみよう

では、先ほどの流れを基に何かしら作ってみます。
前述の図にあった、URLからサイト情報を取得するajaxを実装してみます。
また、ここで使うプラグイン接頭辞はwpmra_とします。

1. アクションフックの追加

ここで追加するアクションフックは、後述するエンドポイントにフックさせることでアクションフックに登録した関数を呼び出すようになっています。
そのため、アクションフックの名前はwp_ajaxと自分で決めたアクション名を繋げたものになります。
wp_ajax_ホニャララホニャララの部分を決めて追加します。
プラグイン接頭辞を含め、以下の様なアクション名と関数名にしました。

add_action('wp_ajax_wpmra_fetch_site_info', 'wpmra_fetch_site_info');

また、フロント側で使いたい場合、WordPressへ未ログインのユーザー向けにwp_ajax_nopriv_ホニャララというフックが用意されているので、そちらを使用します。
ですが、こちらは未ログインユーザー向けのみのものらしく、これだけをアクションフックに追加すると今度はログインユーザーには有効にならないという謎仕様になっております。
ですので、同じ関数を呼び出すアクションフックを2つ追加します。

add_action('wp_ajax_wpmra_fetch_site_info', 'wpmra_fetch_site_info');
add_action('wp_ajax_nopriv_wpmra_fetch_site_info', 'wpmra_fetch_site_info');

2. 登録した関数の作成(JSON返却用)

1.で追加したアクションフックで呼び出している関数wpmra_fetch_site_infoを作成します。

function wpmra_fetch_site_info() {
    $res = array(
        'status' => 'NG',
    );
    if(isset($_POST['post_title'])) {
    // POSTで送信されたURLからRSS情報を取得する
        $rss = get_wpmra_fetch_feed($_POST['post_title']);
        // サイトタイトル、URLを配列へ
        if($rss) {
            $res['status'] = 'OK';
            $res['data'] = array(
                'title' => $rss->get_title(),
                'url' => $rss->get_permalink(),
            );
        }
    }
    // 配列をJSON形式で出力
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode($res);
    exit();
}

// $urlからRSSのFeedデータを取得
function get_wpmra_fetch_feed($url){
    include_once ABSPATH . WPINC . "/feed.php";
    
    $rss = fetch_feed($url);
    if(!is_wp_error($rss)){
        return $rss;
    }
}

簡単に解説しますと、WordPressのwp-includes/feed.phpを使用してRSSのURLからFeed情報を取得し、その中からサイトタイトルとサイトURLをJSON形式で出力しています。
出力後は必ずexit()die()を使って終了させます。

アクションと関数は出来ましたが、JavaScriptでJSONデータを取得するためのURLを知らないといけません。
wp_ajax_のエンドポイントは、サイトURL/wp-admin/admin-ajax.phpになります。
フックに追加した関数を呼び出すには、リクエスト内のactionパラメータにwp_ajax_より後ろに記載した文字列を指定する必要があります。(今回の場合はwpmra_fetch_site_info

3. データ取得するJavaScriptの作成

custom.jsというファイルを作成し、読み込みます。

add_action('admin_enqueue_scripts', 'enqueue_wpmra_script');
function enqueue_wpmra_script(){
    wp_enqueue_script('wpmra_js', '/path/to/custom.js', array('jquery'), '0.1');
}

このjsファイルにデータ取得する処理を書いていきますが、ここで一つ問題が。
先ほどwp_ajax_のエンドポイントはサイトURL/wp-admin/admin-ajax.phpだと説明しましたが、サイトURLは開発環境、テスト環境、本番環境で変わっていきます。
また、この処理をプラグインに実装するとなると、余計に変わります。
JavaScriptにサイトURLの判定処理を書くのも何なので、wp_localize_scriptという関数でPHPからjsに渡すようにします。

PHPファイルにscriptタグで直接書けば良いのでは?という意見もあると思いますが、横着せずPHPはphpファイルに、JavaScriptはjsファイルで管理するよう心がけましょう。

add_action('admin_enqueue_scripts', 'enqueue_wpmra_script');
function enqueue_wpmra_script(){
    wp_enqueue_script('wpmra_js', '/path/to/custom.js', array('jquery'), '0.1');
    wp_localize_script('wpmra_js', 'WPMRAJS', array('endpint' => admin_url('admin-ajax.php')));
}

wp_localize_scriptの第2引数の文字列がcustom.jsでのグローバルオブジェクトになります。
第3引数に渡している配列でWPMRAJSというグローバルオブジェクトに値がアサインされます。

これでJavaScriptを書ける準備が整いましたので、書いていきます。

jQuery(function(){
    // URL情報を取得するボタンを押したらサイト情報を設置する
    jQuery("#wpmra_fetch_site_info").on('click', function(){
            // 記事タイトルに入力されたRSS Feed
        var post_title = jQuery('input[name="post_title"]').val();
        jQuery.ajax({
            url : WPMRAJS.endpoint,
            type : "POST",
            // actionパラメータに、実行したいアクションの「wp_ajax_」より後ろの文字列を指定
            data : {action : 'wpmra_fetch_site_info', post_title : post_title },
            success : function(res){
                if(res.status === 'OK') {
                    jQuery('input[name="mra_rss_title"]').val(res.data.title);
                    jQuery('input[name="mra_rss_feed_url"]').val(res.data.url);
                }
                if(res.status === 'NG') {
                    alert("取得に失敗しました。");
                }
                return false;
            }
        });
    });
});

[Googleアナリティクス]イベントトラッキングで訪問者の詳細な行動を計測する

こんにちは、ニタです。
最近、Webサイトのアクセス解析などに携わるようになりました。
そこで今回は、アクセス解析ではもはや必須ツールとなっているGoogleアナリティクスの話です。
Googleアナリティクスは訪問者の訪問時間や閲覧したページや、どのようにサイト内を移動したかなどができるツールです。

しかし、標準の機能ではページ内のどのリンクが押されたか、ファイルダウンロードリンクで多くダウンロードされたファイルはどれかなどの、サイト独自の訪問者の行動の計測はできません。

そこで、アナリティクスのイベントトラッキング機能を使うことで、訪問者の詳細な行動を計測することができます。

例えば、以下の様なPDFファイルのダウンロードリンクがあるとします。

このリンクの中から、どのファイルがダウンロードされたのかを計測してみます。

<a href="pdf/my_company_info.pdf" class="dl-button" target="_blank">会社案内</a>
<a href="pdf/my_product_info.pdf" class="dl-button" target="_blank">製品紹介</a>
<a href="pdf/my_company_services.pdf" class="dl-button" target="_blank">サービス案内</a>
<a href="pdf/my_company_product_a.pdf" class="dl-button" target="_blank">製品A資料</a>
<a href="pdf/my_company_product_b.pdf" class="dl-button" target="_blank">製品B資料</a>

イベントトラッキング送信のコード

まず、Googleアナリティクスのトラッキングコードはheadタグ内に書いておきます。

<script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

  ga('create', 'UA-XXXXXXXX-NN', 'auto');
  ga('require', 'linkid', 'linkid.js');
  ga('send', 'pageview');
</script>
</head>

続いて、JavaScriptで以下のようなコードでリンクのクリック時のリンク名を計測します。

$(function(){
    $('.dl-button').on('click', function(){
      var file_name = jQuery(this).html();
      ga('send', 'event', 'File Download', 'ダウンロードファイル', file_name);
    });
});

このコードを記載したテストページで、実際にイベントトラッキングをアナリティクスへ送信し、計測結果を見てみます。


 

実際のレポート結果を確認

実際のアナリティクスのレポート画面を見てみると、計測結果が出ています。

今回は、リアルタイム計測のイベント画面で確認しましたが、左メニューの「行動」→「イベント」→「サマリー」、「上位のイベント」からでも確認できます。


 

イベントトラッキングコードについて

先ほどのコード内のga('send','event', ...というコードが、イベント送信のコードになります。
各引数は以下のようになります。

ga('send', 'event&', 'カテゴリ', 'アクション', 'ラベル', 値);

'カテゴリ'以下の引数に渡す内容は以下のとおりです。

send, eventは固定値です。

名前 内容
カテゴリ(必須) 発生するイベントを分類する名称
アクション(必須) カテゴリに対する訪問者の行動名称(例:スクロール、ダウンロード)
ラベル(任意) 細かく分類したい時に使用。
値(任意) イベントに数字を割り当てられる。(例:問い合わせやダウンロード1件あたりの売上額などの数値)

Googleのヘルプには詳細な説明があります。

イベントについて – アナリティクス ヘルプ

Webサイトの訪問者がどのページをどのように閲覧しているのか、サイト内で何をしているか(どういったコンテンツを探しに訪問したのか)が分かれば、今後のサイト更新の方向性に迷いはなくなるでしょう。

 


WordPressでのサイト制作にはVCCWがおすすめ

タグ: , | 投稿日: 投稿者:

新年あけましておめでとうございます。ニタです。

年末年始、いかがお過ごしでしたか?

私はWordPressのプラグインの改修を進めたかったのですが、何かと慌ただしく過ぎてしまいました。
機能追加を計画していますので、もうしばらくお待ちください。

さて、そんなWordPressでのサイト(テーマ)、プラグイン開発で非常に便利なのが今回ご紹介する「VCCW」です。

VCCWって何?

VCCWは、VagrantとChefによるWordPress開発環境ツールです。

ローカル開発環境にインストールするのは、VirtualHostの設定、MySQLのDB登録などの作業だけで、すぐ済むのですが、そういった作業が苦手なデザイナーやHTMLのコーダー、いちいち設定するのが面倒と感じる方もいると思います。

VCCWでは、WordPress単体だけでなく、テーマ・プラグイン制作に役立つツール類もインストールされます。

Vagrantとchefにより、centos上にApache、PHP、MySQL、WordPressなどがインストールされます。

opensslもインストールされるので、フォームなどのSSL環境が必要な状況にも対応しています。

初回起動時にインストールされるツール、プラグイン

  • openssl
  • Grunt
  • Composer
  • rbenv
  • bundler
  • node.js
  • grunt-cli
  • WordPress Unit Tests(PHPUnit)
  • WordPress i18n Tools
  • WP-CLI
  • theme-check (WordPress plugin)
  • dynamic-hostname (WordPress plugin)
  • plugin-check (WordPress plugin)
  • wp-multibyte-patch (WordPress plugin)

利用には、VagrantとVirtualBoxが利用できることが前提となるので、予めインストールしておいてください。

また、Vagrantのプラグインvagrant-hostsupdaterが必要となります。

Vagrantインストール後、以下にてプラグインをインストールしてください。

※今回はmacでのインストール方法のみになります。予めご了承ください。

vagrant plugin install vagrant-hostsupdater

インストール、設定

パッケージのダウンロード

VCCWのサイトにあるzipかtar.gzをダウンロードし、適当なディレクトリに解凍します。

この記事の執筆時のVCCWのバージョンは1.9.6です。

解答すると、「vccw-1.9.6」というディレクトリが作成されます。

Vagrantfileの編集

解凍してできた「vccw-1.9.6」というディレクトリ内にあるVagrantfileがあるので、ターミナルなどでvccwディレクトリに移動し、vagrant upコマンドで開発環境は立ち上がります。
その前に日本向けにVagrantfileを編集します。

  • 15行目、WordPress内のlocaleをjaに。
WP_LANG = ENV["wp_lang"] || "ja" # WordPress locale (e.g. ja) 
  • 70行目、cent os側のWordPressのディレクトリをローカルマシンのディレクトリとsyncさせる。
config.vm.synced_folder "www/wordpress/", "/var/www/wordpress", :create =&gt; "true"

上記の"www/wordpress/"をローカルマシンでWordPressを格納するディレクトリパスに書き換える。

パスが、/Users/nita/workspace/wp-developの場合、

config.vm.synced_folder "/Users/nita/workspace/wp-develop", "/var/www/wordpress", :create =&gt; "true"
  • 113行目、 cent osにインストールされるPHPのタイムゾーンを変更。
"date.timezone" =&gt; "Asia/Tokyo",

起動 確認

Vagrantfileの編集が終わったら、ターミナルなどでVagrantfileがあるディレクトリに移動し、vagrant upコマンドで起動します。

初回起動時は、centosのboxファイルのダウンロードや、apache、PHP、MySQL、WordPressのインストールや設定が行われるので、多少時間がかかります。

また、途中でhostsファイルにVagrantで利用するホストとURLを書き込むため、ローカルマシンのユーザーパスワードを求められます。

無事、起動が成功しますと、以下のURLにてWordPressサイトが表示されます。

http://wordpress.local

また、管理画面は以下のID/パスワードでログインできます。

http://wordpress.local/wp-admin

ID パスワード
admin admin

といった感じです。

WordPressを利用したサイト制作では、WordPressの設定やデータベースの設定など何かと準備が細々とあります。

VCCWを使えば、そんな準備に時間をかけることなく開発作業に臨めると思います。

VCCWには今回紹介した他にも、WordPressでの様々な操作をコマンドラインで実行できる「WP-CLI」やtheme-check、plugin-checkなど便利なツールが使えます。

おまけ

VCCWがデフォルトでインストールしているプラグインやWP-CLIについて説明します。

theme-check

ダウンロードしたテーマや、制作したテーマが、WordPressが設けている品質ガイドラインに準拠しているか、セキュリティホールが開いていないかどうかチェックしてくれます。

plugin-check

制作したプラグイン、インストールしたプラグインが、WordPressの品質ガイドラインに準拠しているかどうか、セキュリティホールが開いていないかどうかをチェックしてくれます。

互換性に問題のある関数が使われていないか、システムコマンドが実行されていないか、プラグイン内でini_set()が使われていないかなど、細々とチェックしてくれます。

WP-CLI

WP-CLIで出来ることをちょっとだけ。

まずは、VCCWの仮想環境にSSH接続しWordPressのディレクトリに移動ます。

vagrant up
vagrant ssh
cd /var/www/wordpress

WordPressのDBのエクスポート

例:mysqldump_wordpress.sqlにエクスポート

wp db export mysqldump_wordpress.sql

WordPressプラグインのアップデート

例:プラグインakismetをアップデート

wp plugin update akismet

また、rbenv、node.js、Grunt、bundlerなどはjQueryのプラグインのインストールやSassのインストールなど、テーマ制作時に利用すれば、色々捗ると思います。

その辺については、また改めて紹介したいと思います。


『リーダブルコード』を読みました。(3)

コードのスタイル、見た目

こんにちは、ニタです。
リーダブルコード第3回目は、「コードのスタイル、見た目」について書きたいと思います。

可読性が高く、読みやすいコードを書くには、分かりやすい変数、関数の命名規則の他に、見た目も意外と大事だと思います。

どんなにバグがなく高速に処理できるプログラムでも、ファイルを開いてみると、コードがゴチャゴチャしていて、理解するのに時間が掛かるようでは、修正する際困るのはコードを書いた自分であり、修正することになる自分を含む誰かです。

コードがキレイだと、さっと流し読みができて理解しやすく、修正、リファクタリングのしやすさに繋がると思います。
では、キレイなコードを書くためには何が重要なのでしょうか。

キレイなコードを書くためのポイント

キレイなコードを書くために気をつけるべきポイント・原則は、この3点だと思います。

  • 読み手が慣れているパターン、一貫性のあるレイアウトを使う
  • 似ているコードは似ているように見せる
  • 関連するコードは1ブロックにまとめる

これらを実施するためには、実際にコードを書く段階でどのような事を行えばいいでしょうか。

一貫性のある簡潔な改行位置

例えば、関数の引数の指定など、コードの改行位置を統一することでコードを見やすくなる場合もあります。

以下は、投稿内容を取得する関数で、ニュースとブログの一覧を取得するコードです。
Post::getList()で必要な引数ごとに改行し、各引数の横にそれぞれの引数が何を意味するのかをコメントで書いてみました。

$news_list = Post::getList(
    'news', // 投稿タイプ
    20, // 1ページあたりの表示件数
    1, // 表示ページ
    true // 降順表示
);

$blog_list = Post::getList(
    'blog', // 投稿タイプ
    10, // 1ページあたりの表示件数
    1, // 表示ページ
    false // 降順表示
);

vimなどで、複数のファイルを同時に表示した際、1行あたりの文字数が限られてしまいます。
そのため、このように縦に長いコードの方が読みやすい場合も出てくると思います。
また、直接引数に値を入力せずに、分かりやすい変数名を決め、変数の上部や後ろにコメントで説明を追記しても良いですが、変数を作るまでもない場合はこのように書くのもアリかと思います。

ただ、上記のように同じメソッドを複数回呼び出す場合だと、縦に長くなるし、同じコメントを何回も書かなければなりません。
書き手も読み手も、ちょっと疲れますよね。

では、どう書けば良いか。
最初のメソッドだけコメントを書いて、以降は書かないというのも、コードのスタイルが統一されておらず、おかしいです。
コメントが書かれているメソッドが削除され、書かれていないメソッドだけが残ったら、途端に引数の内容が分からなくなるでしょう。
また、前述した「似ているコードは似ているように見せる」というポイントからも外れてきます。

このような場合は、下記のように仮の引数を使い、説明用のコメントを用意すると分かりやすくなると思います。

// Post::getList($post_type, $posts_per_page, $page, $is_desc_sort);
//               投稿形式, 1ページあたりの表示件数, 表示ページ, 降順表示するか

$news_list = Post::getList('news',20,1,true);
$blog_list = Post::getList('blog',10,1,false);

メソッドを使った整列、整頓

どんどんコードを書いていくうちに、コードが長く複雑になり、読みにくくなっていく場合もあるでしょう。
その場合、別のメソッドに分けることで、コードを簡潔になるケースもあります。
そうすることで、1つのコードの中で似たような処理を何度も書かなくてはいけない部分を、メソッドの呼び出しだけで済むようになります。

それにより、以下の様な副作用が生じる場合があります。

  • コードが簡潔になり、可読性が上がる
  • メソッドの呼び出しが簡潔になり、テスト用コードの追加が簡単になる

縦の線をまっすぐにする

縦の線、縦の並びを整えるということです。
ちょっと面倒ですが、こんな感じに並びをキレイにすると流し読みしやすくなります。

$detail = $request->post('detail');
$name   = $request->post('name');
$url    = $equest->post('url');
$phone  = $request->post('phone');
$email  = $request->post('email');

こういう感じで。

と、終わりたいところですが、上のコードの中でタイプミスがあります。
どこだか分かりますか?

縦の並びを意識して整列させると、こういったミスを見つけやすくなると思います。
($urlの右辺、$requestが誤字)
でも、手間っちゃ手間です。時間に余裕がある時にやる感じの作業に感じます。
だからやらなくても良いかなとも思います。とは言え、流し読みはしやすくなるなとも感じるので、一概にやらない訳にもいかない作業です。
なので、時間的余裕と、今後そのコードを読む人への親切心がある場合に行う程度の作業と捉えておいてください。

一貫性と意味のある並び

「似ているコードは似ているように見せる」というポイントを実施するための書き方になります。

Webサイトのフォームのコーディングで、inputタグなど同じコードが複数ある場合、タグ内の属性の順番を統一させるなど、統一感を持たせることで、可読性が上がります。

<input type="text" name="name" value=""/>
<input type="text" name="email" value=""/>
<input type="text" name="tel" value=""/>
<input type="text" name="address" value=""/>

タグごとに属性の順番がバラバラだと、コードを読み進めていくうちに一貫性のなさにイライラしたり、逆に意味があるのではないかと疑問に思ったりするかもしれません。

また、そのフォームでの入力内容を制御する側のコードでも、inputタグが書かれた順番に処理していくと、統一感が生まれ理解しやすいコードになると思います。

// 処理する順番を、inputタグの順番に合わせる。
$name = $_POST['name'];
$email = $_POST['email'];
$tel = $_POST['tel'];
$address = $_POST['address'];

inputタグ順など基準となるものがない場合は、重要な項目順、アルファベット順など、ある一定の順番を決めておくといいと思います。

宣言をブロックにまとめる

コードを段落ごとに分割して読みやすくする、ということです。
ハンドラ系ならそれらで一塊に、ヘルパー系ならそれだけの塊でまとめます。
更に、先頭部分にコメントで何のブロックなのか、どういった処理を行うのかなど説明を書いておくと、より分かりやすくなるでしょう。

WordPressのテーマファイルの土台となるファイル群を自動生成する「_s」(underscores)というサービスがあります。

_s

作成したいテーマ名を入力すると、ヘッダー、フッター、サイドバーや基本的なCSSファイルなどを生成してくれます。
その中のstyle.cssには、ファイル内でスタイル定義する内容の一覧表がコメントで書かれています。

更に項目ごと(ヘッダー部分、サイドバー部分)のスタイル定義を開始する前にコメントで、何のスタイル定義なのかを明記しており、手を加えやすい構成になっています。

個人的な好みと一貫性

最後に、個人的な好みに近いことです。
プロジェクト、チームごとの決まり事として、コーディング規約を決めておくと良いよという話です。
ifの「{」をifと一緒の行にするか、1行にするかとか、そういう話ですね。

if($hoge){
}
//もしくは
if($hoge)
{
}

コーディング規約は、個人的な好みで決める前に、使用するプログラム言語にも左右されるので、そこは注意しておく必要があります。

また、プロジェクトや社内ルールなどで決まったコーディング規約があるなら、それに合わせた方が良いでしょう。

規約が曖昧だったり、統一されていないと、コードが読みにくくなります。
プログラム言語、フレームワークによって、規約は様々あります。

まとめ

いつも書いていくと長くなるのですが、まとめてしまうとこんなに簡潔なことになります。

  • 複数のコードブロックで、同じようなコードがあれば、シルエット(見た目)も同じようにすべき。
  • コードの「列」を整列すれば、概要が把握しやすい。
  • 意味ある順番を選び、常に守る。(例:inputの要素の並び)
  • 空行を使い、大きなブロックを論理的な「段落」にする。
  • コーディング規約などプロジェクト、チームごとの規約に準拠した書き方をする。

まずは仕様通りに、期待した動きができるようコードを書き進めるのが第一ですが、書き進めていくなかで、これまで書いてきたコードを振り返ったりする場合もあると思います。
その際に、ゴチャゴチャしすぎて分からなくなるようでは、どんなに動くコードでも、理解できなければ、修正できなければ、いざという時困ったことになります。

そのような事を防ぐためにも、日頃から少しずつ、今回のコードの整理を行うことで、読みやすいコードに近づくことができると思います。
それでは、また。


『リーダブルコード』を読みました。(2)

タグ: | 投稿日: 投稿者:

こんにちは、ニタです。
『リーダブルコード』まとめ、第2回目は変数や関数などの名前について書いていきたいと思います。

良い名前とは?

コードを書いていて、変数名や関数名を決める時、どのように決めていますか?書いているコードの役割、処理の内容を考慮したり、その時の気分だったりでしょうか。

その時の気分で決めるのは、お薦めできませんが、ここでも「理解しやすいコード」を意識した名前付け、「良い名前」が大事になってくると思います。

良い名前とは、変数で言えば、変数の目的や値の内容(実際の値ではなく)がわかり、誤解されないものを指すと思います。

「名は体を表す」と言いますし。
では、良い名前付けには、どういった事を気をつけていけば良いのでしょうか。

明確な単語を選ぶ

曖昧な意味を持つ単語、色々な意味に捉えられる単語は避けたほうが良いでしょう。

ユーザー情報を登録する関数名で、setUserData()に比べてinsertUserData()の方が分かりやすいと思います。SQLのINSERT文で慣れ親しんでいるのもありますし、set…だと何にsetするのか明確ではないと思います。
セッションに登録するのなら、setを使ってsetSession()のような名前だと良いと思います。

また、処理内容の重たさも考慮した名前を選ぶのも重要になってくると思います。
他の人が書いたコードを読んでいて、関数の名前で、その関数が何をしているかおおよそ予想がつく場合もあるでしょう。 

ですが、たまに、よく見かけるgetXXX()のような関数名で、数100行にも渡り、DBの色んなテーブルや外部サービスからデータを取得し計算し…と、複雑かつ時間のかかる処理が書かれている場合もあります。 

get…から始まる関数名は、いろんなコードで見かけるし、これまで何度も書いたことのある関数名だと思いませんか?

なので、getXXX()は「処理が軽そうなイメージ」が持たれるため、前述のような重たい処理の関数の場合は、名前だけでは推測しにくい、普段慣れ親しんでいないような単語を選ぶのが良いと思います。
computeXXX()とかcombineXXX()のようなものに変えてみると、気を引きやすいのではないでしょうか。
もちろん、軽い処理であれば、getXXX()などの慣れ親しんだ単語を使うのは、分かりやすいし良いと思います。

 

他の意味と間違わられないように、状況に合わせた単語選びを

明確な単語を選ぶとしても、1つの動作に対し英単語も結構な数があります。 類語辞典や翻訳サイトや辞典サイトなどで調べて、見栄えの良い単語を使ってみると、他の関数と差別化が図れると思います。

ただし、やり過ぎには注意しましょう。
phpのexplode()とsplit()は、返り値は同じですが、処理方法、引数の内容は異なります。 この2つの関数の違いを名前だけでは判断が出来ません。

また、単語選びを横着して、他の意味に間違われるような単語を選びがちになるケースもあります。
面倒だからと、filter()なんて名前にした場合、何を取捨選択する関数なのかパッと見分かりません。
select(選択)するのかもしれないし、逆にexclude(除外)するのかもしれません。

 

名前に情報がないもの、汎用的な名前は避ける(※ただし状況を選ぶ)

名前だけである程度内容や変数の値が分かるように、いちいち考え、調べて命名している時間がない場合もあるでしょう。
そんな時やってしまいがちなのが、$tmp,$returnなどの汎用的な変数名だと思います。
気持ちはわかるのですが、やはり名前に情報を持たないものは避けた方が良いです。
後から困るのは自分だし、他の人が読んだ時理解するのに時間がかかるでしょう。

ただし、以下の場合は例外として使用してもいいと思います。

  • 使用期間が短く、他に渡されたり何度も書き換えられない。
  • この変数には他の役割がない、他の処理で使えないと分かる場合。

これらに該当しないが、どうしても使いたい場合は、それ相応の理由をコメントなどに明記しておくべきでしょう。

ただし、「時間がない」「適切な名前が思い浮かばない」といった理由は、改修時や他の人がそのコードを読む時に困るので、やめましょう。バグの温床です。

また、ループ処理のイテレータに、i,j,kなどを使用していると思いますが、ループが複数ネストする場合やループが長い場合、どれがどのループのイテレータなのかi,j,kだけでは分かりにくくなりませんか?
そのような場合は、category_i,users_i,orders_iというように、説明的な変数名を使用すると分かりやすいと思います。

 

具体的な名前を使う

たまに、他の関数や変数との差別化を測りすぎて、抽象的な名前になってしまう場合もあるかもしれません。僕も前科があります(笑)。
WordPressのプラグインで、プラグインを有効化した時実行される関数をhelloRucy()、アンインストール時に実行される関数をgoodbyRucy()としてました。
開発当時は、自分が分かれば良いやと名づけたのですが、オープンソースのプラグインでそれは無いなと反省しています。
他の関数、変数と差別化を図る場合は、具体的な名前で考えたほうがいいでしょう。

 

プレフィックス、サフィックスなどを使用し、情報、属性を追加する。

コードが長くなっていって、変数名が一つの単語だけでは分かりにくくなる場合もあるでしょう。

例えば、$startの単位は何なのか?$limitは最大値なのか最小値なのか、単位は何なのか。
$startの場合、単位がミリ秒なら、$start_msというようにサフィックスをつけると分かりやすくなるでしょう。
$limitにしても、$max_page, $min_pageのように限界値を示すプレフィックスを付けると良いでしょう。

範囲を指定するような変数の場合は、$first_…, $last_…または、 $begin_…, $end_…などのプレフィックスに情報を追加して、分かりやすくなると思います。

その他にも、プレフィックスに属性を追加するとコードを追っていかなくても、変数の内容が分かる場合もあります。

  • パスワードを代入する変数$passwordの値が、暗号化前の平文の場合、$plain_passwordとする。
  • ブール値なら、is_…, has_…, can_…, should_…といったプレフィックスを付ける。この場合、肯定形の名前にすると、if文の条件分岐などが分かりやすくなる。

 

名前の長さを決める

具体的で、プレフィックスを追加していくと長い変数名、関数名になっていくでしょう。 打つのが面倒で、短い名前にする場合もあると思います。

ですが、cssで、padding-top:10pxの指定するクラス名「pt10」は、やはり理解するのに時間がかかります。
名前が短すぎると、型とか意味が名前から分からなくなり、バグの温床になります。
また、処理の中で長く使う(スコープが大きい)変数には、長く説明的な名前を付けると、コードを読み進めるときも分かりやすくなるでしょう。

しかし、長すぎる名前で省略しても分かる場合は、短くしても良いでしょう。
ConvertToString()という関数名で、Convertがなくても、ToStringだけでも文字列に変換する関数だとわかると思います。

さて、逐一これまで書いてきたことを実施していくと、時間ばかり取られるのでは?と思うでしょう。
名前を決めるのにも、長くなった変数名を打つのも時間がかかります。
全てに対して実施しなさいということではなく、「変数の意味を取り違えたらバグになりそうな箇所だけ」でもいいと思います。
つまり「変数の意味を理解してもらわないと困る場合」は、変数名をしっかり考えるべきということです。

 

プロジェクト、チーム固有のルール、省略形、頭文字は避ける。

名前の長さやプレフィックス、サフィックスなど命名規約を決めていくのは良いことですが、度が行き過ぎて、プロジェクト固有のルールになり過ぎないよう注意が必要です。
フレームワークを使用している場合(symfony 1.x系のコアクラスにはsfが先頭に付くlowerCamelで書かれています)や、共通認識としてある汎用的な省略形は例外だと思いますが。
また、フレームワークや言語固有の命名規則もあるので、それに則るのも良いでしょう。

 

まとめ

今回も長々と書いてしまいましたが、まとめると、こんな感じになります。

  • 明確な単語を選びを。
  • 汎用的な単語は避け、具体的な名前を使い、内容を詳細に説明する。※明確な理由があれば別
  • 変数名、関数名に重要な情報を追加する。
  • スコープの大きな変数には長い名前を付ける。
  • 独自命名規則は避ける。バグの温床。
  • 最善の名前は、誤解されない名前。

コード内の処理がしっかり動いていても、変数名、関数名がおざなりになっていると、いざメンテナンス、改修時に工数が取られる原因につながります。
多少面倒かと思いますが、気をつけていただければと思います。
それでは、また。