水曜日, 4月 25, 2007

blogger betaにはてなのこのエントリーをブックマークに追加ボタンをつける。

blogger betaにはてなのこのエントリーをブックマークに追加ボタンをつけてみたいと思って検索したときなかなか解説してるページが見つからなかったのでソースを貼り付けておきます。

         <span class='hatena-entry hatena-append'>
            <a expr:href='"http://b.hatena.ne.jp/append?" + data:post.url'><img align='absmiddle' alt='このエントリーをブックマークに追加' height='12' src='http://b.hatena.ne.jp/images/append.gif' style='border: none;' title='このエントリーをブックマークに追加' width='16'/></a>
            <a expr:href='"http://b.hatena.ne.jp/entry/" + data:post.url'><img align='absmiddle' alt='このエントリーを含むはてなブックマーク' expr:src='"http://b.hatena.ne.jp/entry/image/" + data:post.url' style='border: none;' title='このエントリーを含むはてなブックマーク'/></a>
       </span


とりあえず自分のブログのテンプレートにもセットしてますが無意味な気がしてきたのでそのうち削除しようかな。

月曜日, 4月 09, 2007

googleのi'm feeling luckyをfirefoxで。

googleのi'm feeling lucky

(検索結果ページを表示せずに、検索結果1番上のサイトにダイレクトにアクセスする機能)

をfirefoxの検索バーで使いたいなあと思い、検索プラグインを探してみたけどなかなか見つからず、そしたらそもそも

「アドレスバーに検索語を打ち込んでエンターを押す」

とgoogleのi'm feeling luckyの結果ページに飛ぶことがわかった。
どうりで検索プラグインがないわけだ(作るまでもなかったということ)。

水曜日, 4月 04, 2007

web製作者(webプログラマ兼webデザイナー)としてこれができたらひとつ壁越えられるかなと思うこと。

web製作者(webプログラマ兼webデザイナー)としてこれができたらひとつ壁越えられるかなと思うこと。

webプログラマ
・webセキュリティについての知識。
脆弱性の種類の把握・コードを見て脆弱性を見つけられる。・脆弱性に対する対策をコーディングできる。
・ある程度のアルゴリズム・デザインパターンを網羅的に把握していて、簡単なプログラムならすぐに組むことができる。

webデザイナー
・ある程度のロジックを持って、レイアウト・カラーコーディネイトができる。
・グラデーション・ストライプ・ドロップシャドウ・1pxラインなどディテールに注力した素材加工をロジカルにできる。
・アクセント素材をロジカルに作れる。


とくにデザインに関してはとかくセンスの問題かと思われがちだが最低限のレイアウトとカラーコーディネイトはある程度ロジックが存在するっぽい(まだまだそういう記事や本は非常に少ないけど)。ひとつのページ・サイトを作るにあたってのデザインプロセスを組み立てられれば素早くページの作成ができるようになるはず。。

木曜日, 2月 22, 2007

cakephpでwebサービスapiを活用したサンプルサイトを作ってみる4

前回cakephpで作ったシンプルなamazon検索ページをちょっと改良。
セキュリティ的なことがまだ考慮できてないのでデモページは公開せず。
勉強用の参考資料としてソースのみ公開。

今回の改良で、
cakeデイレクトリ/amazon/search/キーワード(日本語の場合はURLエンコード)

というアドレスで検索結果が表示されるようになった。これで直接検索結果にリンクを貼れる。

amazon_controller.php
<?php

class Amazon_Info {
    const ACCECSS_KEY_ID = '自分のamazonwebserviceのアクセスキー';
    // アフィリエイトIDを使いたい場合に指定
    const ASSOC_ID = '自分のアフィリエイトID';
}

require_once 'Services/AmazonECS4.php';

class AmazonController extends AppController {

    var $name = 'Amazon';
    var $uses = array();
    var $helpers = array('Html', 'Form');
    
    function index()
    {
        if(empty($this->
data)) {
            $this->render();
        } else {
            $this->redirect('/amazon/search/'. $this->data['Amazon']['words']);
        }
    }
    
    function search($words = null)
    {
        if(empty($words)){
            $this->render("index");
        } else {
            $amazon = new Services_AmazonECS4(
                Amazon_Info::ACCECSS_KEY_ID,
                Amazon_Info::ASSOC_ID
            );
            
            $result = $amazon->setLocale('JP');
            
            $options['Keywords'] = $words;
            $options['ResponseGroup'] = 'Medium';
            
            $result = $amazon->ItemSearch('Books', $options);
            
            $this->set('words', $words);
            $this->set('result', $result);
            $this->render();
        }
    }
}
?>


index.thtml
<form action="<?php echo $html->url('/amazon'); ?>"
method="post">

        <?php echo $html->input('Amazon/words'); ?>
        <?php echo $html->submit('search');?>
</form>


search.thtml
<form action="<?php echo $html->url('/amazon'); ?>" method="post">

        <?php echo $html->input('Amazon/words', array('value'=>$words)); ?>
        <?php echo $html->submit('search');?>
</form

<?php
foreach ($result['Item'] as $item) {
    displayOne($item);  // 一件分の表示
}

/** 一件分の結果を表示する関数 */
function displayOne($item) {
    $attributes = $item['ItemAttributes'];

    // HTMLで表示して問題の無い形式にエスケープ
    $title = htmlspecialchars(
        $attributes['Title'], ENT_QUOTES);
    if (isset($attributes['Author'])) {
        $author = htmlspecialchars(
            // 複数著者はカンマでまとめる
            implode(',', $attributes['Author']),
            ENT_QUOTES);
    } else {
        $author = '(著者無し)';
    }
    $detailUrl = htmlspecialchars(
        $item['DetailPageURL'], ENT_QUOTES);
    $imageUrl = htmlspecialchars(
        $item['MediumImage']['URL'], ENT_QUOTES);
    $formattedPrice = htmlspecialchars(
        $attributes['ListPrice']['FormattedPrice'], ENT_QUOTES);
    $asin = htmlspecialchars(
        $item['ASIN'], ENT_QUOTES);
    $salesRank = (integer)($item['SalesRank']);

    // 整形して表示
    echo "<h3>
タイトル: ${title}</h3>";
    echo "
<a href=\"${detailUrl}\">";
    echo "
<img src=\"${imageUrl}\" />";
    echo "
</a>";
    echo "
<dl>";
    echo "
<dt>著者</dt><dd>${author}</dd>";
    echo "
<dt>価格</dt><dd>$formattedPrice</dd>";
    echo "
<dt>ASIN</dt><dd>$asin</dd>";
    echo "
<dt>売り上げランク</dt><dd>${salesRank}位</dd>";
    echo "
</dl>";
}
?>


残りの問題
・POSTデータの入力値チェックがされていない(たぶん。cakephp側でなんらかのチェックが自動でなされているのかどうか調査の必要あり)。
・エラー発生時の処理を記述してない。

・なぜか表示が崩れる?
・商品イメージや売上ランク等の情報が取得できなかった場合の処理が必要そう。

・キャッシュ機能が実装されていない。

cakephpでwebサービスapiを活用したサンプルサイトを作ってみる3

とりあえず極力シンプルにamazon検索機能のあるページをcakephpで作成。

amazon_controller.php
<?php

class Amazon_Info {
    const ACCECSS_KEY_ID = '自分のamazonwebserviceのアクセスキー';
    // アフィリエイトIDを使いたい場合に指定
    const ASSOC_ID = '自分のアフィリエイトID';
}

require_once 'Services/AmazonECS4.php';

class AmazonController extends AppController {

    var $name = 'Amazon';
    var $uses = array();
    var $helpers = array('Html', 'Form');
    
    function index()
    {
        if(empty($this->
data)) {
            $this->render();
        } else {
            $words = $this->data['Amazon']['words'];
            
            $amazon = new Services_AmazonECS4(
                   Amazon_Info::ACCECSS_KEY_ID,
                   Amazon_Info::ASSOC_ID
            );
            
            $result = $amazon->setLocale('JP');
            
            $options['Keywords'] = $words;
            $options['ResponseGroup'] = 'Medium';
            
            $result = $amazon->ItemSearch('Books', $options);
            
            $this->set('result', $result);
            $this->render("search");
        } 
    }
}
?>

index.thtml
<form action="<?php echo $html->url('/amazon'); ?>"
method="post">

        <?php echo $html->input('Amazon/words'); ?>
        <?php echo $html->submit('search');?>
</form>


search.thtml
<form action="<?php echo $html->url('/amazon'); ?>"
method="post">

        <?php echo $html->input('Amazon/words'); ?>
        <?php echo $html->submit('search');?>
</form

<?php
foreach ($result['Item'] as $item) {
    displayOne($item);  // 一件分の表示
}

/** 一件分の結果を表示する関数 */
function displayOne($item) {
    $attributes = $item['ItemAttributes'];

    // HTMLで表示して問題の無い形式にエスケープ
    $title = htmlspecialchars(
        $attributes['Title'], ENT_QUOTES);
    if (isset($attributes['Author'])) {
        $author = htmlspecialchars(
            // 複数著者はカンマでまとめる
            implode(',', $attributes['Author']),
            ENT_QUOTES);
    } else {
        $author = '(著者無し)';
    }
    $detailUrl = htmlspecialchars(
        $item['DetailPageURL'], ENT_QUOTES);
    $imageUrl = htmlspecialchars(
        $item['MediumImage']['URL'], ENT_QUOTES);
    $formattedPrice = htmlspecialchars(
        $attributes['ListPrice']['FormattedPrice'], ENT_QUOTES);
    $asin = htmlspecialchars(
        $item['ASIN'], ENT_QUOTES);
    $salesRank = (integer)($item['SalesRank']);

    // 整形して表示
    echo "<h3>
タイトル: ${title}</h3>";
    echo "
<a href=\"${detailUrl}\">";
    echo "
<img src=\"${imageUrl}\" />";
    echo "
</a>";
    echo "
<dl>";
    echo "
<dt>著者</dt><dd>${author}</dd>";
    echo "
<dt>価格</dt><dd>$formattedPrice</dd>";
    echo "
<dt>ASIN</dt><dd>$asin</dd>";
    echo "
<dt>売り上げランク</dt><dd>${salesRank}位</dd>";
    echo "
</dl>";
}
?>


ただし、このコードにはいろんなものを省き過ぎていて以下の問題点と課題がある。

・POSTデータの入力値チェックがされていない(たぶん。cakephp側でなんらかのチェックが自動でなされているのかどうか調査の必要あり)。
・エラー発生時の処理を記述してない。

・なぜか表示が崩れる?
・商品イメージや売上ランク等の情報が取得できなかった場合の処理が必要そう。
・GETクエリではないので直接リンクを貼ったりできない。

・キャッシュ機能が実装されていない。

とりあえずこれを土台にコードの改善を試みてみる。