Webで公開されているAPIからデータを取得したりデータを送信するBehaviorがBakeryで公開されている。
Webservice Behavior (Articles) | The Bakery, Everything CakePHP
HTTP GET、HTTP POST、XMLRPCが使えるようだ。
GETしたいだけならオーバースペックかも。
POSTもcURLを使わずに、PHPでPOSTリクエストを送信する - PHPプロ!ニュースの方がシンプルでいいかも?
参考:CakePHP1.2のBehaviorを使う - 院生エンジニアのにっき
2008年9月20日土曜日
2008年9月19日金曜日
RSS/Atomフィードを生成したりSitemapを作成するPHPライブラリ
P2_Feeder2
(Google独自の)携帯向けサイトマップであるモバイル・サイトマップに対応してるけど、まだBeta版。
Updateが止まっていてAtom1.0に対応していないFeedCreatorの代わりになるか?
(Google独自の)携帯向けサイトマップであるモバイル・サイトマップに対応してるけど、まだBeta版。
Updateが止まっていてAtom1.0に対応していないFeedCreatorの代わりになるか?
2008年9月16日火曜日
CakePHP 1.2 のFormHelperで日付選択リストを作る
$form->datetime()を使うと、年月日(または年月日+時間)を選ぶselect要素が簡単に作れる。
オプションとしてarray('monthNames' => false)を渡すと、月の表示が数字になる
「日」がゼロ埋めなしなのに「月」だけゼロ埋めされているのが嫌な場合は、あらかじめ$form->month or $form->dayにデータをセットしておく。(参考:CakePHP FormHelper#datetime()で年月日表示を変える | Shin x blog)
array_combineを使ったのはoption要素のvalue属性を表示値と同じにするため。
デフォルトでは年が現在から前後20年ずつ、大きい順に表示されて煩わしい。
今年と来年を小さい順に表示するにはこんな感じ。
echo $form->datetime('cal', 'MDY', 'NONE'); // => Septemper-1-2008
//第3引数をNONE以外すると、時間の選択リストも表示される。(デフォルトは"12")
echo $form->datetime('cal', 'MDY', 24);
オプションとしてarray('monthNames' => false)を渡すと、月の表示が数字になる
echo $form->datetime('cal', 'YMD', 'NONE', null, array('monthNames' => false)); // => 2008-01-1
「日」がゼロ埋めなしなのに「月」だけゼロ埋めされているのが嫌な場合は、あらかじめ$form->month or $form->dayにデータをセットしておく。(参考:CakePHP FormHelper#datetime()で年月日表示を変える | Shin x blog)
array_combineを使ったのはoption要素のvalue属性を表示値と同じにするため。
$form->options['month'] = array_combine(range(1, 12), range(1, 12));
echo $form->datetime('cal', 'YMD', 'NONE'); // => 2008-1-1
デフォルトでは年が現在から前後20年ずつ、大きい順に表示されて煩わしい。
今年と来年を小さい順に表示するにはこんな感じ。
$years = range(date('Y'), date('Y') + 1);
$form->options['year'] = array_combine($years, $years);
echo $form->datetime('cal', 'YMD', 'NONE');
Flashでページをめくるライブラリで逆方向にめくる方法
Flashでページをめくるライブラリで、日本の縦書きの本のようにページを左から右へめくるようにする方法。
Page Flip by PiXELWiTの場合
Free PageFlip 2.25 by Iparigrafikaの場合
Page Flip by PiXELWiTの場合
- Actionsレイヤー フレーム2の「gotoAndPlay(4)」を変更し、最初に表示したいページのフレームに行くようにする
(全部で8ページの場合は「gotoAndPlay(13)」) - シンボルBound PagesのActionsレイヤー フレーム1の冒頭にある変数dir, flipPage, curPageの初期値を変更する
- dirは-1にする
- flipPageは表示しているページとその裏のページを足して2で割った値にする
(全部で8ページの場合は7.5) - curPageは表示しているページとその右側のページを足して2で割った値にする
(全部で8ページの場合は8.5)
Free PageFlip 2.25 by Iparigrafikaの場合
- Actionsレイヤー フレーム5の50行目あたりでセットしている変数「directlink」の値を最初に表示したいページ番号にする
または、
directlinkに関する記述(51~53行目)を削除してしまい、直接変数「page」にページ番号をセットしてもOK - 要は、初期処理で変数「page」にセットされたページを最初に表示するようになっているようだ
2008年9月15日月曜日
検索エンジンによる自分のサイトのインデックス状況やSitemapを管理するまとめ
Google:Google ウェブマスター ツール - マイレポート
日本のYahoo!:サイトエクスプローラー(サイト管理者向けツール) - Yahoo!検索
世界のYahoo!:Yahoo! Site Explorer
- サイトマップはモバイル・動画・ニュースなどいろいろ受け付けている
- iGoogleガジェットもここから取得できる
日本のYahoo!:サイトエクスプローラー(サイト管理者向けツール) - Yahoo!検索
- モバイル向けのフィード・サイトマップは受け付けていない
世界のYahoo!:Yahoo! Site Explorer
- モバイル向けのフィード・サイトマップも登録可能(xhtml or wml)
- Yahoo! JapanではなくYahoo.comのアカウントが必要
CakePHP 1.2 で多国語対応(GetText)調査メモ
PHPでは _() または gettext() でgettextできるが、CakePHPではそれをラップして __() でgettextできる。
CakePHPでのgettextについては、CakePHP 1.2 の多言語対応メモ - miau's blog?が、参考サイトへのリンクも多く、よくまとまっていて参考になる。
あとはひっかかりそうなところについてのメモ。
複数形
英語など単数と複数でメッセージが変わる場合、__n() を使う。
Rubyよりも使いやすいと思う。
(2008/09/17 追記)
__n()の第3引数は、シンプルな変数でないと機能しないようだ。sprintfとかの関係だろうか?
言語によってメッセージ内のパラメータの順番が違う場合
翻訳メッセージの複数個所に穴埋めで項目名などを入れる場合で、言語によって順番が違う場合の対応方法。
1.2系の多言語対応メモ(3) - Writing Some Codeの後半を参照。
//PHPの例CakePHPではCakeコンソールからi18nできて便利そう。
echo _('We love PHP');
//CakePHPの例
__('You love CakePHP'); //第2引数でtrueを指定すればechoせずに戻り値を返すこともできる
CakePHPでのgettextについては、CakePHP 1.2 の多言語対応メモ - miau's blog?が、参考サイトへのリンクも多く、よくまとまっていて参考になる。
あとはひっかかりそうなところについてのメモ。
複数形
英語など単数と複数でメッセージが変わる場合、__n() を使う。
//例詳しくは、1.2系の多言語対応メモ(2) - Writing Some Codeを参照。
__n('cat', 'cats', $catCount);
echo __n('mouse', 'mice', $mouseCount, true); //第4引数は戻り値を返すかどうか
Rubyよりも使いやすいと思う。
(2008/09/17 追記)
__n()の第3引数は、シンプルな変数でないと機能しないようだ。sprintfとかの関係だろうか?
//NG(追記終わり)
__n('cat', 'cats', $cat['count']);
//OK
$count = $cat['count'];
__n('cat', 'cats', $count);
言語によってメッセージ内のパラメータの順番が違う場合
翻訳メッセージの複数個所に穴埋めで項目名などを入れる場合で、言語によって順番が違う場合の対応方法。
1.2系の多言語対応メモ(3) - Writing Some Codeの後半を参照。
avast! 4 Home Editionの便利な使い方
「ご家庭 での 非営利使用 にのみ無料」なavast! 4 Home Editionを使うためのメモ。
本家:
無料アンチウイルス - avast! 4 Home Edition ダウンロード
スクリーンセーバー起動時にバックグラウンドでウィルスチェックを行う方法:
avast! 4 Home Edition - Online soft
定期的にウィルスチェックを行う方法:
本家:
無料アンチウイルス - avast! 4 Home Edition ダウンロード
スクリーンセーバー起動時にバックグラウンドでウィルスチェックを行う方法:
avast! 4 Home Edition - Online soft
定期的にウィルスチェックを行う方法:
- 下記内容を書いたバッチファイルを、Windowsの「タスク」で定期的に実行する
(ashQucik.exeへのパスは環境に合わせて変更する。下記は「C:Program FilesAlwil Software」ディレクトリにバッチファイルを置く場合。)@echo off
rem メモリ内をチェックする場合
Avast4ashQuick "*MEMORY"
rem チェックしたいドライブを全て指定する
Avast4ashQuick "C:" "D:" - 途中でウィルス等が見つかると止まっちゃうかも
- 参考:おじいちゃんのメモ - おじいちゃんのメモ-特殊な検査方法
2008年9月6日土曜日
CakePHP1.2の layoutで使える Helperのまとめ
head要素内に記述する要素など、layoutに書く要素のうちHelperで作成できるもののまとめ。
YUI Girdsを使うならこんな感じになる。
少しくらいCSSやJavaScriptを書くだけなら、わざわざHelperを使わずに直接書いた方がいいかも。
JavaScriptは</body>の直前に書きたいが、これでは無理か...?
- ドキュメント宣言 (参考:HtmlHelper::docType)
//引数なしの場合はXHTML1.0 Strict
echo $html->docType(); - Content-Typeのmetaタグ (参考:HtmlHelper::charset)※2008/09/13 誤り修正
//デフォルトはPHPのdefault_charset???
echo $html->charset(); - CSS (参考:HtmlHelper::css)
複数ある場合は配列で渡せる。//webroot/css/foo.cssを読み込む場合
echo $html->css('foo');
//webroot/css/foo.cssとwebroot/css/bar.cssの2つを読み込む場合
echo $html->css(array('foo', 'bar')); - JavaScript (参考:JavascriptHelper::link)
これも配列で渡せる。//webroot/js/foo.jsを読み込む場合
echo $javascript->link('foo');
//webroot/js/foo.jsとwebroot/js/bar.jsの2つを読み込む場合
echo $javascript->link(array('foo', 'bar'));
JavascriptHelperを使う場合、ControllerでこのHelperを有効にしておく。(「s」が小文字なので注意!)var $helpers = array('Html', 'Javascript');
- その他、$html->meta('xxx')で作成できるもの (参考:HtmlHelper::meta)
- RSS ('rss')
- Atomフィード ('atom')
- favicon ('icon')
- デフォルトはwebroot/favicon.ico
- metaタグのkeyword('keyword')
- metaタグのdescription ('description')
YUI Girdsを使うならこんな感じになる。
<<?php ?>?xml version="1.0" encoding="<?php echo ini_get('default_charset'); ?>" ?>
<?php echo $html->docType(); ?>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<?php echo $html->charset(); ?>
<meta http-equiv="Content-Style-Type" content="text/css" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<title><?php echo $title_for_layout; ?></title>
<?php
echo $html->meta('icon', '/favicon.ico'); //サイト全体で共通のfaviconを使う場合
echo $html->css(array('foo', 'bar'));
echo $javascript->link(array('foo', 'bar'));
echo $scripts_for_layout;
?>
</head>
<body>
<div id="doc2" class="yui-t7">
<div id="hd">
ここにヘッダーを書く
</div><!-- #hd -->
<div id="bd"><div class="yui-g"><?php echo $content_for_layout; ?></div></div>
<div id="ft">
ここにフッターを書く
</div><!-- #ft -->
</div><!-- #doc/[2-4]?/ -->
</body>
</html>
少しくらいCSSやJavaScriptを書くだけなら、わざわざHelperを使わずに直接書いた方がいいかも。
JavaScriptは</body>の直前に書きたいが、これでは無理か...?
CakePHPで特殊な用途に使われるテーブルのフィールド名
- id:通常は、Railsと同様に一意になるAuto IncrementなIntegerにする。
ただし、CHAR(36)として作ると自動的に32バイトの「データベースを超えたレベルで」ユニークな文字列が登録される。 - title:Lists等で自動的に使われる文字列になるらしい。
- name:titleと同じ扱い。titleとnameが両方ある場合はtitleが優先される。
- created:登録日時。created_atでないので注意
- modified:更新日時。Railsと同様、timestamp型ではなくdatetime型にする
- updated:modifiedと同じ扱い。こっちの方がしっくりくるのに
CakePHP 1.2で bakeするメモ
CakePHP1.2では、bakeはこんな感じで実行できる。
cakeコマンドはCAKE_HOME/cake/consoleディレクトリにあるが、bakeはアプリケーションを作りたいディレクトリ上で実行する必要がある。WindowsではCakePHP のおいしい食べ方: [1.2]Easy Bake on Windowsを参考にすると楽。オプションとしてappのパスを指定できた。
bakeでのModelの作成はDBのテーブルを元にするので、DBにテーブルが1つも無いと怒られる。
テーブルを作ってからbakeすること。
bakeでModelを作るとオプションでvalidationも付けられる。
が、maxLengthなど値を指定するルールをbakeでどうやって指定するかわからない。
cake bake
cakeコマンドはCAKE_HOME/cake/consoleディレクトリにあるが、
cake -app /path/to/app bake
bakeでのModelの作成はDBのテーブルを元にするので、DBにテーブルが1つも無いと怒られる。
テーブルを作ってからbakeすること。
Welcome to CakePHP v1.2.0.7296 RC2 Console
---------------------------------------------------------------
App : app
Path: CAKE_HOME/app
---------------------------------------------------------------
Interactive Bake Shell
---------------------------------------------------------------
[D]atabase Configuration
[M]odel
[V]iew
[C]ontroller
[P]roject
[Q]uit
What would you like to Bake? (D/M/V/C/P/Q)
> M
---------------------------------------------------------------
Bake Model
Path: CAKE_HOME/app/models/
---------------------------------------------------------------
Error: Your database does not have any tables.
bakeでModelを作るとオプションでvalidationも付けられる。
が、maxLengthなど値を指定するルールをbakeでどうやって指定するかわからない。
CakePHP1.2インストールメモ
CakePHPアプリケーションへのアクセスを http://example.com/cake とする場合のインストール手順のメモ。
(参考:The Cookbook :: 1.2 Collection :: マニュアル :: CakePHPによる開発)
(参考:The Cookbook :: 1.2 Collection :: マニュアル :: CakePHPによる開発)
- ダウンロード
- CakePHPのサイトからアーカイブをダウンロード
- アーカイブを適当な場所(以下CAKE_HOMEと呼ぶ)に解凍
- Apacheの設定
- mod_rewriteは使えるようにしておく
- Alias設定で、CAKE_HOME/app/webrootにアクセスできるようにする
Alias /cake CAKE_HOME/app/webroot
- Directoryごとの設定で、CAKE_HOME/app/webrootへのアクセスを許可する。
AllowOverrideも変更して.htaccessが使えるようにする。(CakePHPのマニュアルではAllにするようなことが書かれているが、mod_rewriteの設定だけならFileInfoで良さそう)<Directory CAKE_HOME/app/webroot>
Order allow,deny
Allow from all
AllowOverride FileInfo
</Directory> - 今回のようにアプリケーションのルートURLをサブディレクトリにする場合、そのままでは404 Bad Requestになってしまうので注意。
CAKE_HOME/app/webrootにある.htaccessにRewriteBaseを追加すればOK。(参考:siwa32.com » CakePHPをはじめる6 サブディレクトリ運用まとめ)<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /cake
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
</IfModule> - 動作確認
- http://example.com/cake/ にアクセスして、CakePHPが動作することを確認
- DB接続の設定(参考:The Cookbook :: 1.2 Collection :: マニュアル :: CakePHPによる開発 :: 環境設定 :: データベースの設定)
(※これはbakeを使っても設定できる) - CAKE_PHP/app/configにあるdatabase.php.defaultをコピーしてdatabase.phpというファイルを作る
- database.phpを編集
var $default = array(
'driver' => 'mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'USER_NAME', //DBユーザー名
'password' => 'PASSWORD', //DBのパスワード
'database' => 'cake', //DB名
'encoding' => 'utf8', //MySQLで日本語を扱うため
); - 編集してから http://example.com/cake/ にアクセスすると、DB関連のメッセージのメッセージがGREENになる
楽天アフィリエイトのPC用 URLと 携帯用URLとの違い
楽天アフィリエイトのPC用URLと携帯用URLの関連性について。公式な資料が無いので推測を元に調査してみる。
楽天Webサービスでの説明を見ると、PC用と携帯用のアフィリエイトURLは別になっている。
楽天のアフィリエイト作成ツールでは、PC・携帯共通URLを作成できる。
例(分かりやすいようにURLデコード&改行してある)
これを見るとPC用URLから携帯用URLを作成できそうだが、楽天の商品URLには下記の2種類のタイプがある。
Bは携帯からも見られる商品用のURL?
いくつかデータを見てみると、Bの場合は色違いなどで複数の商品から選べるアイテムのようだ。この例の場合、"710008" "716540"の2種類。4種類くらいのアイテムもあり、その場合スラッシュ区切りで4つのコードが並ぶ。おそらく最後のシャープ付のIDで内部的には制御してるようだ。
さらに調べると、携帯版の楽天とPC向けの楽天では商品数がかなり違う。PCの方が数倍多い。
しかも、携帯版の楽天はドメインがwww.rakuten.co.jpのアイテムのみが対象になってる(ような気がする)。(数えるほどしか調べてないのでたまたまそういうデータを見ただけかもしれないが。)
ただし、wwwで始まる商品でも携帯版楽天で探してもヒットしないものもあるので、wwwで始まれば携帯からアクセスできるというわけではないようだ。
よく見たらwwwで始まりPCでしかヒットしない商品は全て品切れだった。たくさんのデータで検証したわけではないが、このサブドメインの違いで携帯からのアクセスが可能か判断できそう。
結論(ただし推測)
サブドメインがwwwの商品のみ、携帯版楽天からアクセスできる。その場合、下記のアフィリエイトURLによりPC・携帯で共通のアフィリエイトリンクになる。
(見やすくするために改行したが実際には改行しない。また、パラメータのURL部分はURLエンコードすること)
楽天Webサービスでの説明を見ると、PC用と携帯用のアフィリエイトURLは別になっている。
http://hb.afl.rakuten.co.jp/hgc/[アフィリエイトID]/?pc=[商品URL(PC)]ちなみに、楽天Webサービスで商品URLを取得する場合にはRequestのパラメータとしてPC用か携帯用かどちらかを指定するため、両方の商品URLを1度に取得することはできない。
もしくは、
http://hb.afl.rakuten.co.jp/hgc/[アフィリエイトID]/?m=[商品URL(モバイル)]
楽天のアフィリエイト作成ツールでは、PC・携帯共通URLを作成できる。
例(分かりやすいようにURLデコード&改行してある)
http://hb.afl.rakuten.co.jp/hgc/[アフィリエイトID]/?
pc=http://www.rakuten.co.jp/verjus/827100/665544/705842/#845704
&m=http://m.rakuten.co.jp/verjus/i/845704/
これを見るとPC用URLから携帯用URLを作成できそうだが、楽天の商品URLには下記の2種類のタイプがある。
A. http://item.rakuten.co.jp/monoshop/dul_ch06_k282/Aが昔ながらのURL?
B. http://www.rakuten.co.jp/t-plaza/710008/716540/#727421
Bは携帯からも見られる商品用のURL?
いくつかデータを見てみると、Bの場合は色違いなどで複数の商品から選べるアイテムのようだ。この例の場合、"710008" "716540"の2種類。4種類くらいのアイテムもあり、その場合スラッシュ区切りで4つのコードが並ぶ。おそらく最後のシャープ付のIDで内部的には制御してるようだ。
さらに調べると、携帯版の楽天とPC向けの楽天では商品数がかなり違う。PCの方が数倍多い。
しかも、携帯版の楽天はドメインがwww.rakuten.co.jpのアイテムのみが対象になってる(ような気がする)。(数えるほどしか調べてないのでたまたまそういうデータを見ただけかもしれないが。)
よく見たらwwwで始まりPCでしかヒットしない商品は全て品切れだった。たくさんのデータで検証したわけではないが、このサブドメインの違いで携帯からのアクセスが可能か判断できそう。
結論(ただし推測)
サブドメインがwwwの商品のみ、携帯版楽天からアクセスできる。その場合、下記のアフィリエイトURLによりPC・携帯で共通のアフィリエイトリンクになる。
(見やすくするために改行したが実際には改行しない。また、パラメータのURL部分はURLエンコードすること)
http://hb.afl.rakuten.co.jp/hgc/[アフィリエイトID]/?モバイル用の"i"の部分とかは怪しいかも。
pc=http://www.rakuten.co.jp/[ショップID]/.../.../.../#[商品ID的なもの]
&m=http://m.rakuten.co.jp/[ショップID]/i/[商品ID的なもの]/
2008年9月3日水曜日
Google Chrome
Google Chrome触ってみた。速い速い。昔のOperaを思い出す。それ以上に速い。
JavaScriptコンソールやHTML解析っぽいのもデフォルトで付いてる。
アプリケーションショートカットもなかなか面白い。htaみたい。社内向けシステムとかで余計な上部メニューを消したい場合なんかにもいいかも。
これでExtensionとは言わないまでもGreaseMonkey(CreamMoneky?)くらいあれば乗り換えるかも...。せめてGoogle Customize相当のものがあればなあ。
JavaScriptコンソールやHTML解析っぽいのもデフォルトで付いてる。
アプリケーションショートカットもなかなか面白い。htaみたい。社内向けシステムとかで余計な上部メニューを消したい場合なんかにもいいかも。
これでExtensionとは言わないまでもGreaseMonkey(CreamMoneky?)くらいあれば乗り換えるかも...。せめてGoogle Customize相当のものがあればなあ。
2008年9月1日月曜日
Google Reader Filterで日本語のキーワードを扱う方法
Google Readerで指定したキーワードを含む記事をグレイアウトしたりハイライトしたりするGreaseMonkeyの「Google Reader Filter」。(そのまんまな名前だ。)
日本語が 使えないという指摘があるが、実際には使える。
ただし、キーワードの前後が半角スペースか先頭か末尾でないとヒットしない。
これは日本語に限った話ではないが、単語単位で半角スペースが入る英語では問題が無いため、日本語の問題に見えたのだろう。
具体的なコードの該当箇所は下記のとおり。
なので、日本語をキーワードに使うには、キーワード欄に
キーワードは正規表現として使われるので、他の正規表現を埋め込んじゃってもOK。
逆に正規表現で特別な意味を持つ記号はエスケープしないと正しく動かない。
上記のような書き方が面倒な人は、GreaseMonkeyのファイルを開いて該当箇所を下記のように変更すれば「.*」の記述が不要になる。
キーワードの使い方によっては幅広くヒットしすぎて使い辛そうだが。
日本語が 使えないという指摘があるが、実際には使える。
ただし、キーワードの前後が半角スペースか先頭か末尾でないとヒットしない。
これは日本語に限った話ではないが、単語単位で半角スペースが入る英語では問題が無いため、日本語の問題に見えたのだろう。
具体的なコードの該当箇所は下記のとおり。
_getRegExp:function (items) {JavaScriptと正規表現が読める人には察しが付くだろうが、キーワードをorで繋いで、前に「先頭or半角スペース」、後ろに「末尾or半角スペース」という条件でマッチさせている。
return new RegExp("(^| )("+items.join("|")+")($| )","i");
}
なので、日本語をキーワードに使うには、キーワード欄に
.*あああ.* (「あああ」を含むタイトルをマッチ)というように書けばOK。
いいい.* (「いいい」で始まるタイトルをマッチ)
.*ううう (「ううう」で終わるタイトルをマッチ)
キーワードは正規表現として使われるので、他の正規表現を埋め込んじゃってもOK。
逆に正規表現で特別な意味を持つ記号はエスケープしないと正しく動かない。
上記のような書き方が面倒な人は、GreaseMonkeyのファイルを開いて該当箇所を下記のように変更すれば「.*」の記述が不要になる。
キーワードの使い方によっては幅広くヒットしすぎて使い辛そうだが。
_getRegExp:function (items) {
return new RegExp("("+items.join("|")+")","i");
}