2012年2月20日月曜日

WordPressにAmazonアフィリエイトの商品を貼る



経緯


ギークハウス沖縄のブログでアフィリエイトをやることにしました。


本を頂いたら記事を書き、読んだらレビュー記事を書き、その記事を読んだ方がAmazonで本を買ってくだされば、頂いた本から収益が得られ、そのお金でまた本が買えます。


新しい本が買えると本を寄贈してくださった方も喜んでくださるのではないでしょうか。





ギークハウス沖縄ではブログにfluxflex+WordPressを使用しています。


WordPressでAmazonアフィリエイトのリンクを貼れるようにするのが本記事の目的です。


参考にするサイト


ず's » wordpress用Amazonアフィリエイト用マクロを書いてみた


こちらの記事を参考に進めていきます。


アフィリエイトのマクロを追加する


WordPressのバージョンは3.3.1です。


1.Macro Expanderをインストールする



  1. WordPressの管理画面に入り、左側サイドバーのプラグインから新規追加を選びます。

  2. キーワードの入力欄に「Macro Expander」と入力

  3. プラグインの検索ボタンを押す


f:id:h6n:20120220060138j:image


Macro Expanderが出てきたら、いますぐインストールを押す


f:id:h6n:20120220060139j:image


インストールが完了した、というメッセージを確認する。


f:id:h6n:20120220060140j:image


2.Amazonのリンクを作成するマクロを登録する



  1. 左側サイドバーの外観からテーマ編集を選びます。

  2. 右側のテンプレートの一覧の中から「テーマのための関数」を選ぶ

  3. 「< ?php」の後ろに以下の内容をコピペし、amazon_tracking_idの中の文字を自分のトラッキングIDに変更

  4. ファイルを更新ボタンを押す。


f:id:h6n:20120220060141j:image


確認記事を書く

記事の中で



[[amazon2][427406767X][4873113679]]


のような感じで、amazon2の後ろにasinを角括弧でくくって並べていくだけ。


f:id:h6n:20120220060142j:image


プレビューするとこんな感じ。ちゃんと動いてるっぽい。


f:id:h6n:20120220062329j:image


まとめ


これでAmazonアフィリエイト貼り放題。


ぜひ皆さんもギークハウス沖縄から本を購入してください!





2012年2月19日日曜日

embed.lyを利用してサイトにURLのプレビュー機能を埋め込む方法



#Favtileにembed.lyの埋め込み機能をつけました。


これによりリンク先の動画・写真・OpenGraphで設定されたサイトのアイコン等を埋め込み表示出来るようになりました。


f:id:h6n:20120220000031p:image:w640


今回はembed.lyを利用する過程を紹介します。


embed.lyって何が出来るの?


f:id:h6n:20120220000030p:image:w360


embed.lyを使うと、Webサイトの中に他のサイトの動画や写真やWebサイトを埋め込み表示することが出来ます。


Twitter向けの写真サイト(yfrogやTwitpic)やUstreamやYouTubeはもちろん、InstagramやAmazonなど、218ものコンテンツサイトの埋め込み表示に対応しています。


有料プラン以外に、無料プランがあります。1万URLまで無料で埋め込み表示できます。


登録方法


無料プランへの申し込み方法を説明します。


1.embed.lyの登録画面へ行く

Embedly | Pricing Plans


今回はFreeプランなんで、Freeプランの下のGet this Planをクリック。


f:id:h6n:20120220012134j:image


2.登録画面埋める

まず、ユーザー名、パスワード、メールアドレス、First name、Lastネーム、Organizationの項目を入力しましょう。*1


次にサービスの規約に同意するチェックボックスにチェックを入れます。


最後にSign Up!ボタンをクリックすると完了です。


f:id:h6n:20120220012135j:image


フォーム入力が完了すると次のような画面が出るので、リダイレクトされて別の画面へ切り替わるのを待ちます。


f:id:h6n:20120220012136j:image


この画面が出ると、登録は完了です。


f:id:h6n:20120220012137j:image


embed.lyをウェブサイトで使う前に


embed.lyをウェブサイトで使うためには「このURLのウェブサイトから呼び出されるのを許可する」設定が必要です。


1.設定画面へ行く

Manage your Referrersの欄のManageボタンをクリック


f:id:h6n:20120220024531j:image


2.ウェブサイトのURLを設定に追加する

Add Referrerの入力欄に、WebサイトのURLをhttp://抜きで入力し、Addボタンをクリック。


このとき、「http://favtile.com/hanachin_」など、「http://favtile.com/」のうしろに何かついたURLでもアクセス出来るようにしたい場合は、*をつけて「favtile.com/*」のような感じで入力する。


あと、開発環境がlocalhostのサーバーに上がってるときは




  • localhost/*

  • localhost:3000/*


等々を追加しておくと便利です。


f:id:h6n:20120220024532j:image


追加が完了するとReferrersに出てきます。


f:id:h6n:20120220024533j:image


3.URLが設定出来てるか確認する

自分のウェブサイトで使えるか確認してみましょう。


使いたいURL「http://favtile.com/hanachin_」をTest Urlボタンの左の入力欄に入れ、Test Urlボタンをクリックします。


f:id:h6n:20120220024534j:image


そのURLで使える場合は緑色で「Matched」と出ます。


f:id:h6n:20120220024535j:image


赤で「No match」と出たら、そのURLでは使えません。確認してください。


f:id:h6n:20120220033745j:image


embed.lyを使う


ではembed.lyを実際どうやって使うのかのサンプルです。


全容


<!DOCTYPE html>
<html>
<head>
<title>embed.ly!</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="http://scripts.embed.ly/jquery.embedly.min.js"></script>
<script type="text/javascript">
$(function(){
$("a").embedly({
// ここはそれぞれのAPIキーに置き換えてください
key:"4c0281125b1211e188dc4040d3dc5c07"
});
});
</script>
</head>
<body>
<header>
<h1>embed.ly!</h1>
</header>
<article>
<h1>Favtile</h1>
<a href="http://favtile.com/">Favtile</a>
</article>
<article>
<h1>node.js + socket.io + Arduinoでイイネ! クローン</h1>
<a href="http://www.youtube.com/watch?v=WsjvgkjYWS4">youtube</a>
</article>
</body>
</html>


1.必要なファイルをscriptタグで指定

jQueryと、embed.lyのjQueryプラグインを読み込みます。



<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="http://scripts.embed.ly/jquery.embedly.min.js"></script>


2.embed.lyでリンク先を埋め込む

「"a"」など、埋め込みたいリンクをjQueryで指定し、「$("a").embedly({key: "key"})」のような感じでembed.lyのプラグインを呼び出すだけで、リンクを埋め込めます。



<script type="text/javascript">
$(function(){
$("a").embedly({
// ここはそれぞれのAPIキーに置き換えてください
key:"4c0281125b1211e188dc4040d3dc5c07"
});
});
</script>


keyに指定してある文字はembed.lyのYour API Keyに表示されている文字で置き換えてください。


f:id:h6n:20120220040409j:image


3.確認

確認してみましょう。上手く行けばこのような感じで、サイトの画像や動画が埋め込まれて表示されます。


f:id:h6n:20120220040410j:image


うまくいかなかったらこんな感じでただのリンクのまま、ですね。


f:id:h6n:20120220040411j:image


まとめ


embed.lyを使うと結構簡単な手順で色んなコンテンツを埋め込めるのでお勧めです。


皆さんも是非使ってみてはいかがでしょうか?




*1:キャプチャで「ギークハウス沖縄」って入れてるけど通らなかったので別のに変更しました。





Favtileのユーザーの背景表示をやめました。



#Favtile

前々からフィードバックの意見を貰っていました。



  • Favtileでユーザーが見たいのは背景ではない

  • 背景があると情報過多

一方で背景を表示すると



  • ユーザーの切り替わりが分かりやすい

僕がFavtileに背景画像を設定していた理由は、そのユーザーが設定した背景なのでそのユーザーの雰囲気が出る(かな?)と思っていたからです。

Twitterで背景を設定する理由


Twitterの背景には何の画像を設定していますか?

僕の場合、前までλの画像を敷き詰めていました。

理由は関数型言語、無名関数が好きなんだよアピールのためです。




僕は専用のクライアントでしかTwitterしません。Twitterの背景を設定しても、自分で自分の背景を見ることはほぼないです。

なのでいくらチカチカする画像でも、個性を主張する画像でも、どんな普通な画像でも、気になりません。(見ないから)

もしも僕がケータイでしかTwitterを使わない場合も設定しないと思います。ケータイでは背景を表示する余白のスペースがあるとは思えないからです。




しかし、TwitterのWebサイトでTwitterをやっている人は常に自分が設定した背景画像を目にする事になると思います。

タイムラインを見るときも、自分のお気に入りを見るときも、返信をチェックするときも、サイドバーで他人のプロフィールを表示するときも、常に自分の背景を目にするはずです。

これはパソコンのデスクトップでも同じですよね。

色んな作業をしていても見えるのは自分が設定した背景です。




Twitterのサイトで背景が変わるタイミングはいつでしょう?

別のユーザーのページへ移動した時です。

いつも見えてる背景が変わると別のユーザーのページなんだと気づきやすいですね。

Favtileに背景を設定する理由がない


TwitterのWebの画面と同じように、自分のFavを眺めるなら、自分の背景が見えるのは自然です。

Favtileでは他の人のツイートもだらだらと眺めてもらいたいと思っています。

もしも自分がツイートを眺めるなら、自分が設定した画像がみたいのではないか?

ツイートを眺めるときの背景は、普段のTwitterの背景と同じでいいのか?

他人のツイートを眺めるとき、他の人の背景を見たい訳ではないのでは?

と色々出てきて、背景設定する必要がない事に納得いきました。

まとめ


というわけで、僕の中での結論として

もしも自分がツイートを眺めるなら、自分が設定した画像がみたいのではないか?


という風にまとまって、背景表示をやめました。

大事なのは考えること


背景画像については前々からあったのですが、自分の中での結論が出ていませんでした。

んで色々と突っ込まれても「うーん」みたいな感じではっきりせず。

つけた理由も「その人の雰囲気が出そう」って感じでやっぱりちゃんとした理由なし。(そもそも背景だけでその人の雰囲気が出るのか、その人の雰囲気って必要なのか、とか色々ありますが)

背景についてようやくちゃんと考えてみると「背景画像って作業中にでも眺めたい自分の好きな画像設定してるなー」と気づいて納得して消せました。

レキサスアカデミーで突っ込みいっぱい受けてはじめて「俺あんまり考えてねーなー」と思えた一日でした。

もうちょっと考えて生きていきたい。




2012年2月16日木曜日

生まれて初めてたんぽぽを食べました。



僕が生まれてきてから今まで一度もたんぽぽを食べた事はない。


たんぽぽ茶は飲んだことがあるし、たんぽぽのわたを吹き飛ばすことはあっても、たんぽぽを食べた事は無かった。


人生いつ終わるか分からないのに今たんぽぽを食べないでいつたんぽぽを食べるのか。


たんぽぽの食わず嫌いではないのか。


公園に行けばそこにはたんぽぽがある。いつでもたんぽぽは食べれる。24時間好きなときにたんぽぽ食べれる。


というわけで漫湖公園でたんぽぽを摘んできました。


傷がついてる葉、色が変な葉をのけて水洗い。


サラダでも食べれるらしいのですが、たんぽぽビギナーなのでスパゲッティに混ぜます。


f:id:h6n:20120215181336j:image:w360


鶏肉に塩こしょうで味付けしてたんぽぽと一緒にオリーブオイルで炒め、ゆであがったスパゲッティを加えケチャップを絡める。


f:id:h6n:20120216154430j:image:w360


おいしそう。実際おいしかった。


クリーム系のソースでも食べてみたけどちょっと葉っぱが苦かった。


甘いケチャップとかと一緒だとかなり食べやすい。普通の野菜。見た目も美味しそうです。


僕はたんぽぽを食べることによって、たんぽぽをただの花でなく、食材として見れるようになりました。


たとえ花が咲いてなくても、たんぽぽ見ると「美味しそう」と思える。幸せだ!


これからもたんぽぽに対してもっと仕掛けていきたい。





2012年2月15日水曜日

たべものめも





Arduino + サーボモータ。ボタンを押すと左右に回転!



ボタンを押すとサーボモーターがある方向へ回転、ある程度動くと反対側に動く。


というものを作ってみました。


サーボモータの動かし方を覚えたくて。


なんかすごく楽に行けちゃいましたね。




#include <Servo.h>

#define BUTTON 7

Servo myservo; // create servo object to control a servo
int val = 0;
int direct = 1;
int angle = 90;

void setup()
{
myservo.attach(9); // attaches the servo on pin 9 to the servo object
pinMode(BUTTON, INPUT);
}
// scale it to use it with the servo (value between 0 and 180)
void loop() {
val = digitalRead(BUTTON);

if (angle <= 0) {
direct = 1;
} else if (angle >= 180) {
direct = -1;
}

if (val == HIGH) {
angle = angle + direct;
}

myservo.write(angle);
delay(10);
}





2012年2月14日火曜日

MAMPのPHPでpeclを使う(Mac OSX Lion編)



今日も同居人のデバッグを手伝っています。


PECLでoauthのプラグイン使いたいらしい。


pecl install oauthやるとエラーが出るそうで。


とりあえず以下のブログ参考にしつつやるとpecl install oauth出来た。


MAMP + OAuth + Lion





Rails 3.2 + omniauthでハマった。



Rails 3.2 + omniauthでTwitter連携アプリを作ろうと思いたち、omniauth-twitterを使おうとしてハマったのでメモ。


アクセスすると次のようなエラー



NoMethodError
undefined method `include?' for nil:NilClass

Gemfileでomniauthにgitのリポジトリを設定したら直った。



gem 'omniauth', :git => 'git://github.com/intridea/omniauth.git'





2012年2月13日月曜日

Backbone.jsのTodoアプリを読む。



クライアントサイドMVCフレームワークをもっと勉強したい。


今僕は#Favtileというサービスを作っています。


Twitterのお気に入り機能のためのツールです。


そこではクライアントサイド・サーバーサイド共にCoffeeScriptで書いており、Spine.jsを使っています。


Spine.jsを使いはじめた理由? CoffeeScriptが好きだからです。Spine.jsはCoffeeScriptで書かれていますから。


でも他にもJavaScriptのMVCフレームワークはいっぱいあります。


有名だと思うのでBackbone.jsをやります。


有名だと情報が多いので無名のフレームワークよりも勉強しやすいという考えです。


Backbone.jsのサンプルのTodoアプリを読みながらドキュメントを引いて調べていきます。


Backbone Demo: Todos


Todo Model


Todoモデルはtext、order、doneの3つの属性を持つようです。


属性のデフォルト値がある場合はdefaultsに指定する。


toggleはTodoが完了した/してないを切り替えるメソッドですね。


textの属性持つとコメントには書いてるけどModelの中には「text」が見当たらない。そんなものか。



// Our basic **Todo** model has `text`, `order`, and `done` attributes.
window.Todo = Backbone.Model.extend({

// Default attributes for a todo item.
defaults: function() {
return {
done: false,
order: Todos.nextOrder()
};
},

// Toggle the `done` state of this todo item.
toggle: function() {
this.save({done: !this.get("done")});
}


Backbone.jsのドキュメントを読みながらもっと詳しく読む。


defaults

Modelをインスタンス化するときに属性の値が指定されてなかった時はデフォルト値としてdefaultsの内容が使われる。


ここでdefaultsに関数を指定するとその関数の返り値をデフォルト値として使う、と。


デフォルト値が毎回変わるような場合に関数を指定するといい感じなのかなぁ。


save

Modelのsaveメソッドは、内部でBackbone.syncを使っていて、Backbone.syncではRESTでサーバーにアクセスする。


LocalStorage adapterを使ってるとここが置き換わるかんじか。


saveメソッドに変更したい属性達を{}でまとめて渡すか、save("key", "value")のような感じで呼び出して使う、と。


validateメソッドを実装してvalidateとおらないと保存出来ないようにすることも出来るみたい。


isNewっていうので新規作成されたものか判定してるのかな? 新しく作成されるときはcreateがよばれ、更新の時はupdateが呼ばれるよう。


saveには{success:成功時の処理, error:失敗時の処理}のような感じで成功時・失敗時のコールバック関数を渡せるらしい。


Todo Collection


modelプロパティにCollectionが持ってるモデルのクラスを指定する、Collection.addとかcreateするときにmodelを使うのかなぁ。


Storeっていうのはローカルストレージに読み書きするためのクラスかな?


collectionの中からdoneなやつだけ取るのがdoneメソッドで、remainingはコレクションからdoneなやつを除いたもの、か。読みやすい。


nextOrderでTodoの順番を作ってる。


comparetorプロパティを定義するとcollectionを並べるときにその値が使われるようです。


今のだと追加した順に並ぶようになってますね。



// Todo Collection
// ---------------

// The collection of todos is backed by *localStorage* instead of a remote
// server.
window.TodoList = Backbone.Collection.extend({

// Reference to this collection's model.
model: Todo,

// Save all of the todo items under the `"todos"` namespace.
localStorage: new Store("todos"),

// Filter down the list of all todo items that are finished.
done: function() {
return this.filter(function(todo){ return todo.get('done'); });
},

// Filter down the list to only todo items that are still not finished.
remaining: function() {
return this.without.apply(this, this.done());
},

// We keep the Todos in sequential order, despite being saved by unordered
// GUID in the database. This generates the next order number for new items.
nextOrder: function() {
if (!this.length) return 1;
return this.last().get('order') + 1;
},

// Todos are sorted by their original insertion order.
comparator: function(todo) {
return todo.get('order');
}

});

// Create our global collection of **Todos**.
window.Todos = new TodoList;


TodoView


SpineでいうとControllerにあたる部分。


Backbone.Viewを継承してる。


はtagName、className、id、attributesを指定することで表示用のエレメントが作られ、elプロパティに保持されるようで。


_.template便利だなぁ。クライアントサイドのテンプレートっていっぱいあるのね…


eventsっていうプロパティに{"eventName selector":"methodName"}の形式で書くっぽい。


内部的にはjQueryのdelegateが呼ばれてイベントが設定される。(設定するときには名前空間もくっつけてるみたい)


clickしたときはtoggleDoneがよばれて、その中でmodelのtoggleが呼ばれてdoneの値が更新されて、changeイベントが発行されてレンダリングし直されるのかな。


dbclickではeditが呼ばれて、その中で編集中の見た目になるようクラスを追加して、入力欄にフォーカス当ててるみたい。


ではフォーカスはずれた時はどうなるかというと


renderの中でsetTextをよんでいて、その中で、フォーカスが外れたとき(blur)はcloseを呼ぶように設定してる。


closeの中ではモデルの値を保存したあと、編集中の見た目を取り除いてる感じ。


enterが押された時にもcloseは呼ばれるみたいだ。なるほど。


initializeが初期化する時によばれるものかな?




  • モデルが変更されたらレンダリングしなおす

  • モデルが捨てられたら要素を取り除く


みたいな設定をしてるみたい。



window.TodoView = Backbone.View.extend({

//... is a list tag.
tagName: "li",

// Cache the template function for a single item.
template: _.template($('#item-template').html()),

// The DOM events specific to an item.
events: {
"click .check" : "toggleDone",
"dblclick div.todo-text" : "edit",
"click span.todo-destroy" : "clear",
"keypress .todo-input" : "updateOnEnter"
},

// The TodoView listens for changes to its model, re-rendering.
initialize: function() {
this.model.bind('change', this.render, this);
this.model.bind('destroy', this.remove, this);
},

// Re-render the contents of the todo item.
render: function() {
$(this.el).html(this.template(this.model.toJSON()));
this.setText();
return this;
},

// To avoid XSS (not that it would be harmful in this particular app),
// we use `jQuery.text` to set the contents of the todo item.
setText: function() {
var text = this.model.get('text');
this.$('.todo-text').text(text);
this.input = this.$('.todo-input');
this.input.bind('blur', _.bind(this.close, this)).val(text);
},

// Toggle the `"done"` state of the model.
toggleDone: function() {
this.model.toggle();
},

// Switch this view into `"editing"` mode, displaying the input field.
edit: function() {
$(this.el).addClass("editing");
this.input.focus();
},

// Close the `"editing"` mode, saving changes to the todo.
close: function() {
this.model.save({text: this.input.val()});
$(this.el).removeClass("editing");
},

// If you hit `enter`, we're through editing the item.
updateOnEnter: function(e) {
if (e.keyCode == 13) this.close();
},

// Remove this view from the DOM.
remove: function() {
$(this.el).remove();
},

// Remove the item, destroy the model.
clear: function() {
this.model.destroy();
}

});


AppView


なるほど。既にある要素をelにバインドする事も出来る、と。


addとかresetとかそこらへんのイベントはFAQの中にCatalog of Eventsで載ってる。



// The Application
// ---------------

// Our overall **AppView** is the top-level piece of UI.
window.AppView = Backbone.View.extend({

// Instead of generating a new element, bind to the existing skeleton of
// the App already present in the HTML.
el: $("#todoapp"),

// Our template for the line of statistics at the bottom of the app.
statsTemplate: _.template($('#stats-template').html()),

// Delegated events for creating new items, and clearing completed ones.
events: {
"keypress #new-todo": "createOnEnter",
"keyup #new-todo": "showTooltip",
"click .todo-clear a": "clearCompleted"
},

// At initialization we bind to the relevant events on the `Todos`
// collection, when items are added or changed. Kick things off by
// loading any preexisting todos that might be saved in *localStorage*.
initialize: function() {
this.input = this.$("#new-todo");

Todos.bind('add', this.addOne, this);
Todos.bind('reset', this.addAll, this);
Todos.bind('all', this.render, this);

Todos.fetch();
},

// Re-rendering the App just means refreshing the statistics -- the rest
// of the app doesn't change.
render: function() {
this.$('#todo-stats').html(this.statsTemplate({
total: Todos.length,
done: Todos.done().length,
remaining: Todos.remaining().length
}));
},

// Add a single todo item to the list by creating a view for it, and
// appending its element to the `<ul>`.
addOne: function(todo) {
var view = new TodoView({model: todo});
$("#todo-list").append(view.render().el);
},

// Add all items in the **Todos** collection at once.
addAll: function() {
Todos.each(this.addOne);
},

// If you hit return in the main input field, and there is text to save,
// create new **Todo** model persisting it to *localStorage*.
createOnEnter: function(e) {
var text = this.input.val();
if (!text || e.keyCode != 13) return;
Todos.create({text: text});
this.input.val('');
},

// Clear all done todo items, destroying their models.
clearCompleted: function() {
_.each(Todos.done(), function(todo){ todo.destroy(); });
return false;
},

// Lazily show the tooltip that tells you to press `enter` to save
// a new todo item, after one second.
showTooltip: function(e) {
var tooltip = this.$(".ui-tooltip-top");
var val = this.input.val();
tooltip.fadeOut();
if (this.tooltipTimeout) clearTimeout(this.tooltipTimeout);
if (val == '' || val == this.input.attr('placeholder')) return;
var show = function(){ tooltip.show().fadeIn(); };
this.tooltipTimeout = _.delay(show, 1000);
}

});

// Finally, we kick things off by creating the **App**.
window.App = new AppView;

});


まとめ


だらだらと書いた割に内容のない文章になってしまった。


実際に自分で何か作ってみる方が理解が進むかも。(あるいはBackbone.jsのソースを読むとか)





2012年2月6日月曜日

ローカルにあるgemファイルのインストール



[ruby] ローカルにあるgemファイルをインストールする - プログラム番長のヲボエガキ


ここを参考にして出来た!


gemの-lオプションを使う。



$ gem install -l foo.gem


$ gem instlal -hして確認。



-l, --local Restrict operations to the LOCAL domain