[WordPress] 投稿時間と現在時間の差を表示する2つの方法

「◯分前の投稿」といった表示をWordPressでしたい時のメモです。

方法1.組み込み関数を使って表示する

echo human_time_diff( get_the_time("U"), current_time('timestamp') ) . __(' ago');

ほとんどのケースはこれで大丈夫です。

この場合、日本語だと例えば「1分前」と表示されて問題ないのですが、英語だと「1 day ago」と表示され「a day ago」と表示することができません。

「1 day ago」でも問題はないのですが、これが気になるという場合は、方法2の独自関数を作って対応するのが良いと思います。

方法2.独自関数で投稿時間と現在時間の差を表示する

本当は別に独自関数を作る必要はないのだけど、方法1.の関数を知らずに作ってしまったのでメモがてら残しておきます。

(本当は英語対応もhuman_time_diff()が1だったらaにするとかすればOKという話は置いておくとして)

注意点は、WordPressではPHPの組み込み関数のtime()が出力するのは常にUTCとなっているので、JSTと比べると9時間ずれてしまうというとこです。

これを回避するには、current_time()かdate_i18n()を使います。

function the_time_diff(){
    global $post;
    $seconds_ago = intval( current_time( 'timestamp' ) ) - intval( get_the_time( 'U', $post->ID ) );

    $years_ago = intval( floor( $seconds_ago / ( 3600 * 24 * 30 * 365 ) ) );
    $months_ago =  intval( floor( $seconds_ago / ( 3600 * 24 * 30 ) ) );
    $weeks_ago = intval( floor( $seconds_ago / ( 3600 * 24 * 7 ) ) );
    $dates_ago = intval( floor( $seconds_ago / ( 3600 * 24 ) ) );
    $hours_ago = intval( floor( ( $seconds_ago / 3600 ) % 24) );
    $minutes_ago = intval( floor( ( $seconds_ago / 60 ) % 60 ) );

    if ( $years_ago === 1 ) :
        _e('a year ago');
    elseif ( $years_ago > 1 ) :
        echo "{$years_ago}".__(' years ago');
    elseif ( $months_ago === 1 ) :
        _e('a month ago');
    elseif ( $months_ago > 1 ) :
        echo "{$months_ago}".__(' months ago');
    elseif ( $weeks_ago === 1 ) :
        _e('a week ago');
    elseif ( $weeks_ago > 1 ) :
        echo "{$weeks_ago}".__(' weeks ago');
    elseif ( $dates_ago === 1 ) :
        _e('a day ago');
    elseif ( $dates_ago > 1 ) :
        echo "{$dates_ago}".__(' days ago');
    elseif ( $hours_ago === 1 ) :
        _e('an hour ago');
    elseif ( $hours_ago > 1 ) :
        echo "{$hours_ago}".__(' hours ago');
    elseif ( $minutes_ago === 1 ) :
        _e('a minute ago');
    elseif ( $minutes_ago > 1 ) :
        echo "{$minutes_ago}".__(' minutes ago');
    elseif ( $seconds_ago === 1 ) :
        _e("a second ago");
    else :
        echo "{$seconds_ago}".__(' seconds ago');
    endif;
}

[WordPress] Transient APIがW3TCでAPCを有効にすると動作しない件

Transient APIを使ってキャッシュをしようしても正常に動作しない。

環境と事象

環境:
PHP 5.4.45
APC 3.1.15dev
WordPress 4.3.1
W3 Total Cache 0.9.4.1

具体的な事象としては、

  • set_transient()をするとtrue
  • get_transient()で保存したキャッシュを取得しようとするとfalse
  • W3 Total CacheのObject Cache Method:をDiskにすると正常に動作

といった感じです。

TransientAPIが動作しない原因

WordPressのバージョンを更新した時に発生したので、おそらくW3 Total CacheのオブジェクトキャッシュとWordPress本体のTransient APIが何らかのコンフリクトを起こしているのかと思いました。

これを詳しく調べると泥沼にはまりそう&原因がわかってもWordPressとプラグイン側の問題だとしたらあまり手を出したくないので、今回は以下の解決策で対処しました。

TransientAPIのエラー解決策

1. オブジェクトキャッシュにAPCを使わない

Diskにするとパファーマンスは落ちますが、正常に動作します。

eAcceleratorやmemcachedは試していないので不明です。

2. APCを直接操作する

オブジェクトキャッシュをAPCのユーザーキャッシュにストアするには、なにもTransient APIを使う必要はありません。

APCが有効されているPHPでは、apc_store()やapc_fetch()といった関数でAPCのキャッシュを操作できます。

ぞれぞれ、下記のようにset_transient()など同じように引数をとります。APCを利用する場合は、ほぼ同様に使うことができるのではないでしょうか。

apc_store ( string $key , mixed $var [, int $ttl = 0 ] )
apc_fetch ( mixed $key [, bool &$success ] )

$key:一意なキー
$var:保存する値
$ttl:保存期間

なので、set_transient()をapc_store()に、get_transient()をapc_fetch()にそれぞれ変更すれば動作すると思います。

注意点:APCはPHP CLIからは実行できない

PHP CLIからはAPCは動かないので、テスト用スクリプトを書いてターミナルで実行してもfalseになるので注意が必要です。

(これで数時間無駄にしました。。。)

[WordPress] 外部サーバーの画像参照のために画像のベースURLを変更する方法

例えば、ローカル開発環境をつくっていてデータベースは同期しているけど、画像などは重いからローカル環境に置きたくないという時の対処法です。

今回の簡単な要件

環境は以下のような状況とします。

ローカル開発環境
URL → http:/localhost

本番環境
URL → http://production.com

であると、ローカル開発環境に本番環境のデータをインポートしても、localhost/wp-content/uploadsには画像がないため、当たり前ですが画像は表示されません。

そこで、画像はhttp://production.com/wp-content/uploads以下のものを参照したいとします。

画像のパスをoptions.phpから変更

まずは、http://localhost/wp-admin/options.phpにアクセス。

それぞれ、以下のように入力します。

upload_path:画像ディレクトリの名前(この場合、uploads) 
upload_url_path:画像パスのURL(この場合、http://production.com/wp-content/uploads)

wordpress_change_image_path

あとは、「変更を保存」とするだけでOKです。

[WordPress] Poeditを使った多言語化の翻訳ファイル作り方

WordPressを多言語化する必要があり、翻訳ファイルを作成しました。

WordPressではテーマの翻訳は基本的にlanguagesディレクトリに入れることとなっています。

そして、翻訳情報を入れたpoファイルとそれを元にコンパイルしたmoファイルの2つで1セットを使います。

Poeditをインストール

公式サイトからインストールします。

有料版もありますが、普通に使う分なら無料版でも十分対応できます。

Poeditを起動

起動すると以下のような画面が出てきます。すでに翻訳ファイルがある場合は、「翻訳を編集」または「翻訳プロジェクトを新規作成」を選択。

「WordPressのテーマ・プラグインを編集」は無料版の場合は使用できないので、今回はスルーします。

poedit1

翻訳ファイル(新規カタログ)を1から作成する

1から翻訳ファイルを作るには、メニューのファイル>新規カタログから新規の翻訳ファイル(.poファイル)を作成します。

次に翻訳先言語を選択。

poedit2

Command + S で一旦カタログを保存します。すると「プロジェクト名-ja.po」「プロジェクト名-ja.mo」の2つが生成されます。

翻訳部分を「ソースから抽出」

次に翻訳部分を抽出するために、「ソースから抽出」を選択します。

poedit3

「ソースの検索パス」にWordpressのフォルダを追加します。「+」のマークでできます。

poedit5

次に「ソース中のキーワード」を選択。WordPressなら翻訳の関数「_e()」と「__()」があるので、ぞれぞれ()をとった「_e」「__」を登録して起きます。

poedit5

翻訳の開始

読み込みが正常にできれば、以下のような画面になります。エラーの場合は、下記のエラーの場合の対処法を確認してください。

poedit8

「ソーステキスト」が翻訳元なので、「翻訳」のテキストエリアに翻訳を記入していきます。

全部記入したら保存してから、ファイル> MOにコンパイルをすることで完了します。

エラー:「ソースから抽出」で「カタログの更新に失敗しました」となる

「ソースから抽出」をすると、以下のようなエラーとなることがあります。

poedit6

ちゃんと検証してないですが、登録した翻訳用関数(WordPressだと__()や_e()が該当)の近くに日本語があるとエラーとなる様子。

関数の直前または直後のコメントアウトの中に日本語がある場合に起こるっぽいです。対策として、前後にコメントアウトがある場合は消すか英語にしてみてください。

TwentyFifteenを独自テンプレートにカスタマイズする方法

シンプルなWordPressのテンプレートを探していたところ、意外と「TwentyFifteen」が良さそうだったのでカスタマイズしてみました。

0. ファイル構成

TwentyFourteenに比べるとファイルも少なくなっているので良いですね。

ちゃんと見てないですが、style.css内のメディアクエリもブレークポイントが少なくなっているようでカスタマイズしやすそうです。

content*.phpといったファイルは、WordPressループなどを含むコンテンツの表示用のファイル。

また、inc/以下のファイルはfunctions.phpで読み込まれるカスタマイズ用のファイルです。

404.php 404 テンプレート
archive.php アーカイブ
author-bio.php 著者情報
comments.php コメント
content-link.php リンクポストフォーマット用
content-none.php コンテンツがない時用
content-page.php 固定ページ用
content-search.php 検索結果
content.php メインとなるコンテンツ表示
footer.php フッター
functions.php テーマのための関数
header.php ヘッダー
image.php 画像添付テンプレート
inc/back-compat.php WordPress4.1未満用
inc/custom-header.php カスタムヘッダー用
inc/customizer.php テーマカスタマイザー
inc/template-tags.php テンプレートタグ
index.php メインインデックスのテンプレート
page.php 固定ページテンプレート
search.php 検索結果
sidebar.php サイドバー
single.php 単一記事の投稿
style.css スタイルシート
rtl.css RTL スタイルシート

2. functions.phpから不要なコードを消す

WordPress4.1未満用の互換性確保のために back-compat.php を読み込む部分。
今回は不要なので削除。

/**
 * Twenty Fifteen only works in WordPress 4.1 or later.
 */
if ( version_compare( $GLOBALS['wp_version'], '4.1-alpha', '<' ) ) {
  require get_template_directory() . '/inc/back-compat.php';
}

twentyfifteen_setup()内の不要な設定を削除。

言語ファイルの設定。一部英語化してしまうけれど、あとで修正するので削除。

/*
* Make theme available for translation.
* Translations can be filed in the /languages/ directory.
* If you're building a theme based on twentyfifteen, use a find and replace
* to change 'twentyfifteen' to the name of your theme in all the template files
*/
load_theme_textdomain( 'twentyfifteen', get_template_directory() . '/languages' );

ポストフォーマットの登録。使わない人は削除。

/*
 * Enable support for Post Formats.
 *
 * See: https://codex.wordpress.org/Post_Formats
 */
add_theme_support( 'post-formats', array(
  'aside', 'image', 'video', 'quote', 'link', 'gallery', 'status', 'audio', 'chat'
) );

テーマを管理画面からカスタマイズする用(カスタムヘッダーなど)不要なので削除。

$color_scheme  = twentyfifteen_get_color_scheme();
$default_color = trim( $color_scheme[0], '#' );

// Setup the WordPress core custom background feature.
add_theme_support( 'custom-background', apply_filters( 'twentyfifteen_custom_background_args', array(
  'default-color'      => $default_color,
  'default-attachment' => 'fixed',
) ) );

custom-header.php、customizer.phpは不要なので削除。

/**
 * Implement the Custom Header feature.
 *
 * @since Twenty Fifteen 1.0
 */
require get_template_directory() . '/inc/custom-header.php';

/**
 * Customizer additions.
 *
 * @since Twenty Fifteen 1.0
 */
require get_template_directory() . '/inc/customizer.php';

3. 不要なファイルを消す

functions.phpを編集した後に、下記のファイルを削除。

rtl.css
back-compat.php
custom-header.php
customizer.php
content-link.php

4. カスタマイズ

To be Updated...