Re: WordPressで自動生成されるrobots.txt

WordPressの場合、ダッシュボードの「プライバシー設定」にあわせて自動でrobots.txtを生成してくれます(自分で robots.txt を設置した場合はそちらが優先されます)。

細かな設定を行いたい場合は自分で robots.txt を作成した方が早いかも知れませんが、当該部分にフィルターが用意されているので、プラグインやテーマでカスタマイズすることも可能です。

WordPressで自動生成されるrobots.txt | Gatespace's Blog

惜しい、Function Reference/do robots にもあるようにdo_robotstxt アクションフックが直前で呼ばれるので、そのアクションフックで robots_txt フィルターフックを登録したほうが確実。

<?php
add_action('do_robotstxt', function(){
  add_filter('robots_txt', function($output) {
    $public = get_option( 'blog_public' );
    if ( '0' != $public ) { // open
      $output .= "Disallow: /members/n";
    }
    return $output;
  }
}

Re: Amimotoからstaticpress-s3で静的ホスティング連携

名前もお好きに、とりあえず、wp_update_siteurl.sh とかで。EC2のメタデータを取得して、その情報でデータベースを更新するようにしました。

#!/bin/bash

_id=`curl -s 169.254.169.254/latest/meta-data/instance-id/ | sed -e "s/-/_/"`
_dns=`curl -s 169.254.169.254/latest/meta-data/public-hostname/`
mysql -u root ${_id} <<_EOT_

update wp_options set option_value = 'http://${_dns}' where option_name = 'siteurl';
update wp_options set option_value = 'http://${_dns}' where option_name = 'home';

_EOT_

Amimotoからstaticpress-s3で静的ホスティング連携

武田さん、ありがとうございます。
でも、このままだと不完全で、実は WordPress では wp_options の他にも wp_posts 内に画像ファイルのURLとかを投稿した時の home_url を元に絶対パスで保存してたりするんです。
wp-cli ってツールを使うと、そんな値を一括で置換してくれる search-replace という便利なコマンドが有ります。
網元AMIには、最初から wp-cli 入っているので、wp-cli をインストールしたりする必要は無いです。

てことで、こんな感じで wp_update_siteurl.sh を作ればおっけー

#!/bin/bash
WP_ROOT="/path/to/wordpress"
WP_CLI="/usr/local/bin/wp –path=${WP_ROOT}"
_old_url=`${WP_CLI} eval "echo home_url();"`
_dns=`curl -s 169.254.169.254/latest/meta-data/public-hostname/`
$WP_CLI search-replace ${_old_url} http://${_dns}

view raw
wp_update_siteurl.sh
hosted with ❤ by GitHub

2行目の “/path/to/wordpress” の所は、適宜自分の環境に合わせて変更してください。

Re: How do I extend fetch_feed timeout?

As a quick fix I just went straight for the SimplePie code that the WordPress code is wrapping around.

$feed = new SimplePie();
$feed->set_feed_url('http://rss.betfair.com/RSS.aspx?format=rss&sportID=7');
$feed->set_timeout(30); // set to 30 seconds
$feed->set_item_limit(40);
$feed->set_stupidly_fast(true);
$feed->enable_cache(true);
$feed->set_cache_duration(200);
$feed->init();
$feed->handle_content_type();

WordPress › Support » How do I extend fetch_feed timeout?

WordPress の fetch_feed() 関数でタイムアウト値を延ばす方法をググったらサポートのこの回答が出てきたんだけど、wp-includes/feed.php 眺めたら、アクションフックがあったので、こっちで対応できるねというお話。

add_action('wp_feed_options', function(&$feed, $url){
    $feed->set_timeout(30); // set to 30 seconds
}, 10, 2);

今日の教訓:ググる前にソースを見よう。

Re: [WordPress]コピペでOK!カテゴリー、タグ、パンクズを呼び出すサンプルコードいろいろ

さらっと流し読みしただけですが…

現在読み込んでいる記事の、カテゴリーリンクを1つ出力します。記事が属するカテゴリーが1つだけの場合に有効です。記事一覧を表示するループ内などで使うのが一般的です。
その1. サンプルコード

    $cat = get_the_category();
    echo '<a href="'.get_category_link($cat[0]->term_id).'">'.$cat[0]->name.'</a>';

[WordPress]コピペでOK!カテゴリー、タグ、パンクズを呼び出すサンプルコードいろいろ

get_the_cateory() ですが、内部的には get_term() を呼び出してます。
そんで get_term() では、なにがしかのエラーがあった場合 WP_Error オブジェクトを返すことがあるので、このまま使うと WP_Error オブジェクトが返ってきたときに $cat[0]->term_id とかが存在せずにエラーになってしまいます…
( see. https://core.trac.wordpress.org/browser/tags/3.8/src/wp-includes/taxonomy.php#L933 )

そんなわけで、get_the_category() の返り値は is_wp_error() で検査してから使った方が幸せになれると思うよ。
# ってか the_category() とか標準のテンプレートタグ使えば良いのに…

Re: WordPressで更新・お知らせ履歴を別ページで作る方法

WordPressで、更新履歴やお知らせ履歴をリスト表示したシンプルな別ページを作って、トップページやサイドバーからiFrameやphpのinclude等で呼び出したいケースがあります。
方法は色々ありそうです。私がクライアントさんのサイトで行った方法を紹介します。少々強引です。

私が実施した方法は、固定ページ内に更新履歴やお知らせ履歴のループをPHPで書いてしまう方法です。Exec-PHPプラグインを利用すれば、固定ページ内でPHPを実行することができます。

WordPressで更新・お知らせ履歴を別ページで作る方法

色々、最悪です。

まず、顧客案件で Exec-PHP を使うなんてもってのほか。
例えば、お客さんが以下のようなコードを通常記事に打ったら、MySQL のユーザーアカウント/パスワードが漏洩してしまいます。

<?php
echo DB_USER ."\n";
echo DB_PASSWORD."\n";
?>

まぁ、これは極端な例ですが…

Exec-PHP を入れているサイトの投稿者アカウント(管理者権限が無いアカウントでも!)が漏れてしまった場合、攻撃者は好きなだけサーバ上で php コードを実行できるので非常に危険です。
このプラグインを使うのはやめましょう。

あと、メインクエリーの中で query_posts() 使うなとか色々言いたいことはありますが…

この案件の場合はショートコードを用意してやるのが良いです。こんな感じ。

<?php
add_shortcode('recent_posts', 'my_recent_posts');
function my_recent_posts($atts) {
// デフォルトテンプレート
$template = '<div style="border-bottom:dotted 1px #aaaaaa;margin-bottom:20px;font-size:14px">
<div class="title"><a href="%s" target="_top">%s</a></div>
<div class="day" style="font-size:12px;color:#999999">%s</div>
</div>
';
// 引数の処理
extract(shortcode_atts(array(
'template' => $template,
'args' => 'post_type=post&posts_per_page=10',
), $atts));
$the_list = '';
// 最新のポスト取得
$posts = get_posts($args);
foreach ($posts as $post) {
$the_list .= sprintf(
$template,
esc_attr(get_permalink($post->ID)),
esc_html($post->post_title),
mysql2date("Y年m月j日", $post->post_date)
);
}
return $the_list;
}

これで、固定ページ中に [recent_posts] ってショートコードを書いてやれば表示できるようになります。

追記:
もしくは、テーマテンプレート内にウィジェットエリアを用意して「最近の投稿」ウィジェットを使っても良いねって指摘もありました。

そっちの方が簡単かもですね。やりやすいほうで。

追記2:
似たようなことをやるプラグインもあるそうです。

Re: phpで日本の祝日や振替休日を出力する。

とりあえず1か月分の祝日を取得します。ついでに振替休日やら、国民の休日にも対応してみました。国民の休日なんてめったにあるもんじゃないんですけど、2015年にまたあるようなので、とりあえず実装してみました。イベントスケジュールとかを作るときに結構便利です。

via. phpで日本の祝日や振替休日を出力する。 ::: Toro_Unit

引数には、年も指定できた方が良いですね。

<?php
function get_holidays_this_month($year, $month){
// 月初日
$first_day = mktime(0, 0, 0, intval($month), 1, intval($year));
// 月末日
$last_day = strtotime('-1 day', mktime(0, 0, 0, intval($month) + 1, 1, intval($year)));
$holidays_url = sprintf(
'http://www.google.com/calendar/feeds/%s/public/full-noattendees?start-min=%s&amp;start-max=%s&amp;max-results=%d&amp;alt=json&#39; ,
'japanese__ja@holiday.calendar.google.com' ,
date('Y-m-d', $first_day) , // 取得開始日
date('Y-m-d', $last_day) , // 取得終了日
31 // 最大取得数
);
if ( $results = file_get_contents($holidays_url) ) {
$results = json_decode($results, true);
$holidays = array();
foreach ($results['feed']['entry'] as $val ) {
$date = $val['gd$when'][0]['startTime'];
$week = date('w',strtotime($date));
$title = $val['title']['$t'];
$holidays[$date] = $title;
if( $week == 0) {
$nextday = date('Y-m-d',strtotime('+1 day', strtotime($date)));
$holidays[$nextday] = '振替休日';
}
$before_yesterday = date('Y-m-d',strtotime('-2 day', strtotime($date)));
if(isset($holidays[$before_yesterday])){
$yesterday = date('Y-m-d',strtotime('-1 day', strtotime($date)));
$holidays[$yesterday] = '国民の休日';
}
}
ksort($holidays);
}
return $holidays;
}

[2014-8-26 追記] Google Calendar API v3 に対応させる記事を書きました
[PHP] Google Calendar API v3 で日本の祝日を取得する

Re: WordPressで提供する Web API #wacja2012

Web APIであるからには、JavaScriprからも利用可能なJSON形式にも対応したい。PHPのjson_encode()という関数で変換して出力する。

via. WordPressで提供する Web API #wacja2012

僕の作ったプラグインで実装できるよ。
WordPress › Feed JSON « WordPress Plugins

こんな感じ

情報を増やしたり、フォーマットを変えたい時はプラグインに含まれている feed-json-template.php ってファイルをテーマディレクトリ内に feed-json.php って名前でコピーして色々修正してね。

Re: WordPress使いならこれだけはやっておきたい本当のセキュリティ対策10項目

8. 管理画面にIP制限をかける

wp-adminとwp-login.phpにアクセスできるホストを信頼できるIPアドレスのみに制限する方法です。たとえパスワードがそのまま外部に流出したとしても、社外から管理画面に入ることができなくする対策です。ただ、これは自由にログインさせるコミュニティサイトでは無理ですし、そうでない場合でも利便性が低下しますので、ケース・バイ・ケースで行うべき対策でしょう。

via.WordPress使いならこれだけはやっておきたい本当のセキュリティ対策10項目

惜しい、非常に惜しい。
セキュリティ対策としては良いんですが、これやっちゃうと一部のプラグインが動作しなくなったりしてハマりポイントになる可能性があります。

WordPress で Ajax を実装するためには、以下のような手法が良く用いられます。

add_action('wp_ajax_example', 'ajax_example');  // ダッシュボード用
add_action('wp_ajax_nopriv_nlmg_example', 'ajax_example');  // 公開部分用
function ajax_example(){
    // なんか処理
}

via.いまさらだけどWordPressでAjaxのやり方

こうすると、/wp-admin/admin-ajax.php?action=example にアクセスすることで、簡単に ajax が実装できます。

本当は、公開部分では /wp-admin/admin-ajax.php を使わずにプラグイン独自で用意した方が良いし、Codex にもプラグインのメインPHPファイルまたは補助ファイルでやれと書いてあるんですが、結構上記のような実装をするプラグイン作者が多いです。
すいません、私もたまにやります。
( WordPress は公開部分用に /wp-admin/admin-ajax.php ではなくて、別の API を用意してくれないかなー。 /wp-ajax.php とかで良いんだけど )

なので、IP 制限をする場合は /wp-admin/admin-ajax.php だけは、制限をかけないようにしてあげてください。

Re: Twitterのツイートを表示する-RSS編

公式ウィジェットで十分綺麗なので良いんですが
なんとなく自分で実装したいと思って調べてみたところ

あくちーさん( @actywav )のサイトを見つけました!!
WordPress のプラグイン無しですごく簡単にツイート表示しよー : actyway

ふむふむ。やることは大まかにこの3つの様です。

  • functions.phpに処理実装
  • CSS調整
  • jquery.totemtickerの設置

:
なるほど!キャッシュですか!先生!
ということでTransients APIについては
全く知らなかったので、これを使う方向でカスタマイズしようと思ったのですが・・・

どうやら今回使用しているsimplexml_load_file関数と、Transients APIは
相性が悪いらしく、一旦実装を断念しました・・・。
※調べた所、simplexml_load_file関数はシリアライズ処理が上手くいかないのだそうです。
via. Twitterのツイートを表示する-RSS編 | Web-Clutch

ってわけで、Transients API に対応させてみた。未検証。

<?php
function get_tweet_lines($userName){
date_default_timezone_set('Asia/Tokyo');
$rssUrl = 'http://twitter.com/statuses/user_timeline/&#39;.$userName.'.rss';
// get cache
if ( ($response = get_transient(md5($rssUrl))) === false ) {
$response = wp_remote_get($rssUrl);
if( !is_wp_error( $response ) && $response["response"]["code"] === 200 ) {
set_transient(md5($rssUrl), $response, 60 * 60 ); // 60sec * 60min = 1hour
} else {
$response = false;
}
}
if( $response && !is_wp_error($response) ) {
$rssData = simplexml_load_string($response["body"]);
echo '<ul id="vertical-ticker" class="tweet-widget">';
foreach($rssData->channel->item as $item){
$pubDateJP = date("Y/m/d H:i:s",strtotime($item->pubDate));
echo "<li>".str_replace("\n",'',$item->description)."<p><a href='".$item->link."'>".$pubDateJP."</a>&nbsp;のつぶやき。</p></li>\n";
}
echo '</ul>';
} else {
// Handle error here.
}
}

view raw
get_tweet_lines.php
hosted with ❤ by GitHub

Re: WordPressで記事のツイート数だけを取得して表示する方法

先日設置しましたメニューバー下の新着記事サムネイルに、その記事のツイート数を表示してみました!
いろんなサイトを見て「いいなぁ」と思っていたのでけっこー感動。いいわぁw

ということで、記事のツイート数を取得して表示する方法と、この斜め三角をどうやって作ったかを解説したいと思います!

via. WordPressで記事のツイート数だけを取得して表示する方法 | NANOKAMO BLOG

これだと、記事にアクセスがあったときに毎回 Twitter API 叩いて、Twitter サーバーにいらん負荷をかけちゃうので、WordPress の Transient API 使って、キャッシュを取得するようにしたほうが良いと思う。
あと WP 使うんなら file_get_contents() ではなく、wp_remote_get() 使ったほうが、何かと便利。

<?php
/*
* Get Social Button Count twitter
*/
function get_social_counts( $url ){
$transient_key = md5('get_social_counts-' . $url);
// get cache
if ( false === ($counts = get_transient($transient_key)) ) {
$counts = array();
//twitter tweetcount
$response = wp_remote_get('http://urls.api.twitter.com/1/urls/count.json?url=&#39; . urlencode($url));
if( !is_wp_error( $response ) && $response['response']['code'] === 200 ) {
$decode_tweetcount = json_decode($response['body']);
$twitter_tweetcount =
isset($decode_tweetcount['count'])
? $decode_tweetcount['count']
: 0;
} else {
$twitter_tweetcount = 0;
}
//set array
$counts['twitter'] = $twitter_tweetcount;
// set cache
set_transient($transient_key, $counts, 60*60*1); // expires 60sec * 60min * 1 = 1hour
}
return $counts;
}

※未検証です。