2010年12月19日日曜日

HTML中のクエリパラメータについて -2-

HTML中のクエリパラメータについて書いたけど
その続き。


html中にあるhref属性にて
クエリ文字列の区切りを「&」としても「&」としても
どっちでもステータスバーには「&」と表示され、
リクエストは「&」で送信されます。


でも、javascriptのlocation.href, replaceなどを使った場合、
ブラウザによって挙動が異なります。


以下のようなコードを書いて実行すると、
  1. location.replace('http://search.yahoo.co.jp/search?p=href+smgl&aq=-1&oq=&ei=UTF-8&fr=top_ga1_sa&x=wrt');  



IEの場合

※Internet Explorer 8で実験

 → 「&」が「&」となってリクエストが送信されます。

Firefoxの場合

※Firefox 3.6.12で実験

 → 「&」が「&」のままリクエストが送信されます。


で、HTTPの仕様としてはどうなのだろうと思って調べたけど
どのページを見ていいか分からず...

たぶん「&」が正しいと思うんだけどなー

2010年12月18日土曜日

HTML中のクエリパラメータについて

以下のページにあるように、html中に記述するときは、&ではなくて&

でも、リクエストを送信するときは、ちゃんと&で送信するように!

http://www.ietf.org/rfc/rfc1866.txt


8.2.1. The form-urlencoded Media Type

The default encoding for all forms is `application/x-www-form-
urlencoded'. A form data set is represented in this media type as
follows:

1. The form field names and values are escaped: space
characters are replaced by `+', and then reserved characters
are escaped as per [URL]; that is, non-alphanumeric
characters are replaced by `%HH', a percent sign and two
hexadecimal digits representing the ASCII code of the
character. Line breaks, as in multi-line text field values,
are represented as CR LF pairs, i.e. `%0D%0A'.

2. The fields are listed in the order they appear in the
document with the name separated from the value by `=' and
the pairs separated from each other by `&'. Fields with null
values may be omitted. In particular, unselected radio
buttons and checkboxes should not appear in the encoded
data, but hidden fields with VALUE attributes present
should.


NOTE - The URI from a query form submission can be
used in a normal anchor style hyperlink.
Unfortunately, the use of the `&' character to
separate form fields interacts with its use in SGML
attribute values as an entity reference delimiter.
For example, the URI `http://host/?x=1&y=2' must be
written `<a href="http://host/?x=1&#38;y=2"' or `<a
href="http://host/?x=1&amp;y=2">'.

HTTP server implementors, and in particular, CGI
implementors are encouraged to support the use of
`;' in place of `&' to save users the trouble of
escaping `&' characters this way.

2010年11月22日月曜日

何も書けません...

いろいろ忙しいです。

2010年11月11日木曜日

Mayaa ループ

前回は値の出力(属性への出力も)を実施したので、
今回はループ。

あとは、条件分岐をやれば、だいたいのページは生成できると思います。



さて、こんなテーブルを作りたいことありますよね。

たとえば、一覧出力画面とかで。


  1. <table border="1" frame="box" id="addressTable">   
  2.  <tr>   
  3.   <td width="80" align="center"><b>顧客コード</b></td>   
  4.   <td width="80" align="center"><b>顧客氏名</b></td>   
  5.   <td width="200" align="center"><b>住所</b></td>   
  6.  </tr>   
  7.    
  8.  <tr>   
  9.   <td align="center">00000001</td>   
  10.   <td align="center">terasoluna1</td>   
  11.   <td align="center">東京都中央区</td>   
  12.  </tr><tr>   
  13.   <td align="center">00000002</td>   
  14.   <td align="center">田中</td>   
  15.   <td align="center">東京都中央区</td>   
  16.  </tr><tr>   
  17.   <td align="center">00000003</td>   
  18.   <td align="center">鈴木</td>   
  19.   <td align="center">東京都中央区</td>   
  20.  </tr><tr>   
  21.   <td align="center">00000004</td>   
  22.   <td align="center">高橋</td>   
  23.   <td align="center">千葉県成田市</td>   
  24.  </tr><tr>   
  25.   <td align="center">00000005</td>   
  26.   <td align="center">小池</td>   
  27.   <td align="center">東京都中央区</td>   
  28.  </tr><tr>   
  29.   <td align="center">00000006</td>   
  30.   <td align="center">鈴木</td>   
  31.   <td align="center">東京都足立区</td>   
  32.  </tr><tr>   
  33.   <td align="center">00000007</td>   
  34.   <td align="center">佐藤</td>   
  35.   <td align="center">東京都国立市</td>   
  36.  </tr><tr>   
  37.   <td align="center">00000008</td>   
  38.   <td align="center">青木</td>   
  39.   <td align="center">東京都渋谷区</td>   
  40.  </tr><tr>   
  41.   <td align="center">00000009</td>   
  42.   <td align="center">山本</td>   
  43.   <td align="center">東京都中野区</td>   
  44.  </tr><tr>   
  45.   <td align="center">00000010</td>   
  46.   <td align="center">山下</td>   
  47.   <td align="center">東京都三鷹市</td>   
  48.  </tr>   
  49. </table>  




で、以下の状況を想定。


  • requestスコープに、listAddressというjava.util.List型のオブジェクトがある

  • Listの中身はPOJOで、customerCode, customerName, customerAddressが存在する



htmlは↓のかんじ


  1. <table border="1" frame="box" id="addressTable">  
  2.  <tr>  
  3.   <td width="80" align="center"><b>顧客コード</b></td>  
  4.   <td width="80" align="center"><b>顧客氏名</b></td>  
  5.   <td width="200" align="center"><b>住所</b></td>  
  6.  </tr>  
  7.   
  8.  <tr m:id="loop">  
  9.   <td align="center"><span m:id="_customerCode">dummy code</span></td>  
  10.   <td align="center"><span m:id="_customerName">dummy name</span></td>  
  11.   <td align="center"><span m:id="_customerAddress">dummy address</span></td>  
  12.  </tr>  
  13. </table>  




で、mayaaは↓のかんじ


  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <m:mayaa xmlns:m="http://mayaa.seasar.org">  
  3.     <m:for m:id="loop"  
  4.             m:init="${ var i = 0 }"  
  5.             test="${ i < listAddress.size() }"  
  6.             m:after="${ i++ }" replace="false">  
  7.        <m:exec script="${ var info = listAddress.get(i); }" />  
  8.        <m:doBody />  
  9.     </m:for>  
  10.   
  11.     <!-- 顧客コード -->  
  12.     <m:write m:id="_customerCode"  
  13.             value="${info.customerCode}" />  
  14.   
  15.     <!-- 顧客氏名 -->  
  16.     <m:write m:id="_customerName"  
  17.             value="${info.customerName}" />  
  18.   
  19.     <!-- 顧客住所 -->  
  20.     <m:write m:id="_customerAddress"  
  21.             value="${info.customerAddress}" />  
  22. </m:mayaa>  




ここでポイントなのが、<m:doBody />タグ。
これがないと、↓のようなhtml出力されてしまいます。



  1. <table border="1" frame="box" id="addressTable">   
  2.  <tr>   
  3.   <td width="80" align="center"><b>顧客コード</b></td>   
  4.   <td width="80" align="center"><b>顧客氏名</b></td>   
  5.   <td width="200" align="center"><b>住所</b></td>   
  6.  </tr>   
  7.    
  8.  <tr></tr><tr></tr><tr></tr><tr></tr><tr></tr><tr></tr><tr></tr><tr></tr><tr></tr><tr></tr>   
  9. </table>  



Mayaaのドキュメントには、以下のように書いてあります。


割り当てられたタグのボディを処理します。for プロセッサなどタグのボディが有効なプロセッサで動作します。通常は明示的に使用することはありませんが、Mayaa ファイル側のボディに attribute 以外のプロセッサや空白 (タブ文字、改行を含む) 以外の文字列を記述した場合、doBody を使用しなければタグのボディが処理されません。


つまり、簡単にいうと、forプロセッサのボディを評価したければ、<m:doBody />を書け、と。
この場合だと、を評価しないとinfoが使えませんので、ぜひ<m:doBody />を付けてください。


ちなみに、<m:for />にreplace="false"を付けないと、が消えてしまい、
以下のようなhtmlが出力されてしまいます。


  1. <table border="1" frame="box" id="addressTable">   
  2.  <tr>   
  3.   <td width="80" align="center"><b>顧客コード</b></td>   
  4.   <td width="80" align="center"><b>顧客氏名</b></td>   
  5.   <td width="200" align="center"><b>住所</b></td>   
  6.  </tr>   
  7.    
  8.    
  9.   <td align="center">00000001</td>   
  10.   <td align="center">terasoluna1</td>   
  11.   <td align="center">東京都中央区</td>   
  12.    
  13.   <td align="center">00000002</td>   
  14.   <td align="center">田中</td>   
  15.   <td align="center">東京都中央区</td>   
  16.    
  17.   <td align="center">00000003</td>   
  18.   <td align="center">鈴木</td>   
  19.   <td align="center">東京都中央区</td>   
  20.    
  21.   <td align="center">00000004</td>   
  22.   <td align="center">高橋</td>   
  23.   <td align="center">千葉県成田市</td>   
  24.    
  25.   <td align="center">00000005</td>   
  26.   <td align="center">小池</td>   
  27.   <td align="center">東京都中央区</td>   
  28.    
  29.   <td align="center">00000006</td>   
  30.   <td align="center">鈴木</td>   
  31.   <td align="center">東京都足立区</td>   
  32.    
  33.   <td align="center">00000007</td>   
  34.   <td align="center">佐藤</td>   
  35.   <td align="center">東京都国立市</td>   
  36.    
  37.   <td align="center">00000008</td>   
  38.   <td align="center">青木</td>   
  39.   <td align="center">東京都渋谷区</td>   
  40.    
  41.   <td align="center">00000009</td>   
  42.   <td align="center">山本</td>   
  43.   <td align="center">東京都中野区</td>   
  44.    
  45.   <td align="center">00000010</td>   
  46.   <td align="center">山下</td>   
  47.   <td align="center">東京都三鷹市</td>   
  48.    
  49. </table>   

2010年11月9日火曜日

Mayaa 値の挿入

Mayaaについて書いてみる。

まあ、に書いてあるんだけど、
ここには、目的別に書いてみる。


セッション中の値を表示する



●表示

  1. ようこそ○○さん  



みたいな出力をしたい場合があります。
もちろん、「○○」はセッション中の動的な値で。

そういうときは、

前提

  • セッション中にuserInfoオブジェクトが存在する

  • userInfoにはuserName属性があり、そのgetter/setterが存在する(この場合setterは関係ないかも)

  • ちなみにuserNameはjava.lang.String型である



●html

  1. ようこそ<span m:id="userName">○○</span>さん  



などと書きます。
もちろん、htmlの先頭には、


  1. <html lang="ja" xmlns:m="http://mayaa.seasar.org">  



と書いておきます。

で、mayaaファイルには


  1. <m:write m:id="userName" value="${session.userName}" />  


javascript:void(0)
って書けばOKです。


value属性にセッション中の値を表示する



上では要素として?の出力を書きましたが、
属性値に書きたい場合もありますね。

こんな場合を想定↓

●表示は省略。
テキストボックス中のvalueに出力したい場合

1. 想定するケースとしては、入力画面でsubmitしたあと、入力エラーがあって、画面を再表示する場合
2. 変更画面で、現在の値を入力しておいてあげる優しさを見せたいとき


そういうときは、

前提

  • セッション中にuserInfoオブジェクトが存在する

  • userInfoにはuserName属性があり、そのgetter/setterが存在する(この場合setterは関係ないかも)

  • ちなみにuserNameはjava.lang.String型である



●html
  1. 変更後のユーザ名: <input type="text" name="updateUserName" size="20" value="" m:id="userName">  


などと書きます。

で、mayaaファイルには


  1. <m:echo m:id="userName">  
  2.   <m:attribute name="value" value="${session.userName}" />  
  3. </e:echo>  



って書けばOKです。
これで、valueの中に動的な値を出力できます。

2010年11月3日水曜日

Javaテンプレートエンジン [Mayaa]

pythonとか使ってて思うことですが、
強力なテンプレートエンジンがあるってことは
その言語の魅力だなーと。

で、Javaには無いのかーってことで
Mayaa

結構気になってたんだけど
なかなか使う機会なく,,,


ちゃんとドキュメント読んだのは初めてですが、
これはいい!と思ったのはレイアウト。

レイアウト共有

JSPだと、各ページ共通のものをincludeでガチガチ書かないとダメですが、
このレイアウトの発想を待ってました!

要は、基本となるlayout.htmlがあって、
各ページで異なる部分をそこにインサートしていく、と。


詳細は次回。

2010年10月31日日曜日

OAuth Examples (Python) を読んでみる

OAuthが必要になったので勉強してます。
とりあえず、Google先生に聞いて概要は理解したけど
ソースを読まないことにはなんともならん、と。

で、

OAuth Examples

を読んでみた。
Pythonなので、
AppEngine-OAuth-Library by Mike Knapp (more)
ってところです。


OAuthの流れ。
自サイトとTwitter連携の話。

 Consumerは自サイト
 Service ProviderはTwitter
Userはあなた

twt-tnkというサイトを作りました。

これが自サイトとします。





0.ConsumerはService ProviderからあらかじめOAuth利用許可を得る

このステップは,具体的にはService ProviderにConsumer登録を行い,Consumer KeyとConsumer Secretという値を取得することで行います。
これは、事前の登録で、Twitterにそのページがあります。


開発者
連携アプリの追加と設定はこちらから変更できます。


ってところです。


1.UserがConsumerに,Service Providerから認可が必要な情報へのアクセス権を取得するように指示する。

自サイトにある「Twitterにログイン」的なリンクを用意し、それをUserが押す行為です。

twt-tnk画面上部に「Twitterアカウントでログインする 」ってのがあり、
「/login」というURLになってます。


2.ConsumerはバックグラウンドでService Providerにアクセスし,未認可のRequest Tokenを取得する

自サイトがバックグラウンドでTwitterにアクセスし、未認可のRequest Tokenを取得します。

  1. def get(self, mode=""):  
  2.   
  3.         #TwitterClient、Cookiesクラスの作成  
  4.         (client, cookie) = CreateClientAndCookie(self)  
  5.   
  6.         #Twitterの認証画面表示  
  7.         if mode == "login":  
  8.             #Twitterの認証画面へリダイレクトする  
  9.             return self.redirect(client.get_authorization_url())  
  10.   
  11. def CreateClientAndCookie(self):  
  12.   
  13.     #Twitter認証画面からのコールバック用URLを設定  
  14.     callback_url = "%s/verify" % self.request.host_url  
  15.   
  16.     #TwitterClientクラスの作成  
  17.     client = oauth.TwitterClient(CONSUMER_KEY, CONSUMER_SECRET,  
  18.         callback_url)  
  19.     #Cookiesクラスの作成  
  20.     cookie = Cookies(self, max_age=COOKIE_EXPIRE_TIME)  
  21.   
  22.     return client, cookie  



3.ConsumerはUserをService Providerにリダイレクトさせる。この際Consumerは未認可のRequest TokenをURL Parameterに付加する

自サイトはUserをTwitterにリダイレクトさせます。Request TokenをGETパラメータに付与して。

上のソースを見ると、loginときたら、すぐにself.redirect(client.get_authorization_url())としていますが、

実は、client.get_authorization_url() の中でちゃんとTwitterにアクセスしてRequest Tokenを取得しています。
自サイトの「Twitterアカウントでログインする」を押すと、ちゃんと
http://twitter.com/oauth/authorize?oauth_token=
にアクセスしているのがブラウザ上で分かります。

  1. def get_authorization_url(self):  
  2.   """Get Authorization URL."""  
  3.   
  4.   token = self._get_auth_token()  
  5.   return "http://twitter.com/oauth/authorize?oauth_token=%s" % token  
  6.   
  7. def _get_auth_token(self):  
  8.   """Get Authorization Token. 
  9.  
  10.   Actually gets the authorization token and secret from the service. The 
  11.   token and secret are stored in our database, and the auth token is 
  12.   returned. 
  13.   """  
  14.   
  15.   response = self.make_request(self.request_url)  
  16.   result = self._extract_credentials(response)  
  17.   
  18.   auth_token = result["token"]  
  19.   auth_secret = result["secret"]  
  20.   
  21.   # Save the auth token and secret in our database.  
  22.   auth = AuthToken(service=self.service_name,  
  23.                    token=auth_token,  
  24.                    secret=auth_secret)  
  25.   auth.put()  
  26.   
  27.   # Add the secret to memcache as well.  
  28.   memcache.set(self._get_memcache_auth_key(auth_token), auth_secret,  
  29.                time=20*60)  
  30.   
  31.   return auth_token  


ちなみに、TwitterClientはこんなかんじ。
  1. class TwitterClient(OAuthClient):  
  2.   """Twitter Client. 
  3.  
  4.   A client for talking to the Twitter API using OAuth as the 
  5.   authentication model. 
  6.   """  
  7.   
  8.   def __init__(self, consumer_key, consumer_secret, callback_url):  
  9.     """Constructor."""  
  10.   
  11.     OAuthClient.__init__(self,  
  12.         "twitter",  
  13.         consumer_key,  
  14.         consumer_secret,  
  15.         "http://twitter.com/oauth/request_token",  
  16.         "http://twitter.com/oauth/access_token",  
  17.         callback_url)  


ちなみにちなみに、バックグラウンドでリクエスト送ってる箇所は↓のかんじ

  1. def make_async_request(self, url, token="", secret="", additional_params=None,  
  2.                    protected=False, method=urlfetch.GET):  
  3.     """Make Request. 
  4.  
  5.     Make an authenticated request to any OAuth protected resource. 
  6.  
  7.     If protected is equal to True, the Authorization: OAuth header will be set. 
  8.  
  9.     A urlfetch response object is returned. 
  10.     """        
  11.     payload = self.prepare_request(url, token, secret, additional_params,  
  12.                                    method)  
  13.     if method == urlfetch.GET:  
  14.         url = "%s?%s" % (url, payload)  
  15.         payload = None  
  16.     headers = {"Authorization""OAuth"if protected else {}  
  17.     rpc = urlfetch.create_rpc(deadline=10.0)  
  18.     urlfetch.make_fetch_call(rpc, url, method=method, headers=headers, payload=payload)  
  19.     return rpc  
  20.   
  21.   def make_request(self, url, token="", secret="", additional_params=None,  
  22.                                       protected=False, method=urlfetch.GET):  
  23.     return self.make_async_request(url, token, secret, additional_params, protected, method).get_result()  
  24.     



4.UserはService Provider上でConsumerへのアクセス権委譲を許可する。この際Service Providerは未認可のRequest Tokenを認可済とする

Userは、Twitterのページで、「許可する」といったボタンを押下し、アクセス権委譲を許可します。
すると、TwitterはRequest Tokenを認可済としてくれます。




5.Service ProviderはUserをConsumerにリダイレクトさせる。この際Service Providerは認可済のRequest TokenをURLに含める

TwitterはUserを自サイトにリダイレクトしてくれます。
このとき、GETパラメータに認可済みのRequest Tokenが付与されてます。


6.ConsumerはバックグラウンドでService Providerと通信を行い,認可済のRequest Tokenを実際のアクセス権を示すAccess Tokenと交換する

自サイトはバックグラウンドでTwitterと通信を行い、認可済のRequest TokenをAccess Tokenと交換してもらいます。

リダイレクトされたら、自サイトは以下の処理をします。

  1. #-----------------------------------------------------------  
  2. #OAuthの認証後に、アクセストークンをCookieに保存  
  3. #-----------------------------------------------------------  
  4. def VerityAuth(self, client, cookie):  
  5.     auth_token = self.request.get("oauth_token")  
  6.     auth_verifier = self.request.get("oauth_verifier")  
  7.     user_info = client.get_user_info(auth_token, auth_verifier=auth_verifier)  
  8.   
  9.     #アクセストークンをCookieへ保存  
  10.     cookie["user_token"] = user_info["token"]  
  11.     cookie["user_secret"] = user_info["secret"]  
  12.     cookie["screen_name"] = user_info["username"]  


client.get_user_info(auth_token, auth_verifier=auth_verifier)で、認可済のRequest TokenをAccess Tokenと交換してもらっています。

  1. def get_user_info(self, auth_token, auth_verifier=""):  
  2.   """Get User Info. 
  3.  
  4.   Exchanges the auth token for an access token and returns a dictionary 
  5.   of information about the authenticated user. 
  6.   """  
  7.   
  8.   auth_token = urlunquote(auth_token)  
  9.   auth_verifier = urlunquote(auth_verifier)  
  10.   
  11.   auth_secret = memcache.get(self._get_memcache_auth_key(auth_token))  
  12.   
  13.   if not auth_secret:  
  14.     result = AuthToken.gql(""" 
  15.       WHERE 
  16.         service = :1 AND 
  17.         token = :2 
  18.       LIMIT 
  19.         1 
  20.     """self.service_name, auth_token).get()  
  21.   
  22.     if not result:  
  23.       logging.error("The auth token %s was not found in our db" % auth_token)  
  24.       raise Exception, "Could not find Auth Token in database"  
  25.     else:  
  26.       auth_secret = result.secret  
  27.   
  28.   response = self.make_request(self.access_url,  
  29.                               token=auth_token,  
  30.                               secret=auth_secret,  
  31.                               additional_params={"oauth_verifier":  
  32.                                                   auth_verifier})  
  33.   
  34.   # Extract the access token/secret from the response.  
  35.   result = self._extract_credentials(response)  
  36.   
  37.   # Try to collect some information about this user from the service.  
  38.   user_info = self._lookup_user_info(result["token"], result["secret"])  
  39.   user_info.update(result)  
  40.   
  41.   return user_info  



7.Consumerは6)で得られたTokenを利用して,特定の情報にアクセスする


その他のメソッドなど。
  1. def _get_memcache_auth_key(self, auth_token):  
  2.   
  3.   return "oauth_%s_%s" % (self.service_name, auth_token)  
  4.   
  5. def _extract_credentials(self, result):  
  6.   """Extract Credentials. 
  7.  
  8.   Returns an dictionary containing the token and secret (if present). 
  9.   Throws an Exception otherwise. 
  10.   """  
  11.   
  12.   token = None  
  13.   secret = None  
  14.   parsed_results = parse_qs(result.content)  
  15.   
  16.   if "oauth_token" in parsed_results:  
  17.     token = parsed_results["oauth_token"][0]  
  18.   
  19.   if "oauth_token_secret" in parsed_results:  
  20.     secret = parsed_results["oauth_token_secret"][0]  
  21.   
  22.   if not (token and secret) or result.status_code != 200:  
  23.     logging.error("Could not extract token/secret: %s" % result.content)  
  24.     raise OAuthException("Problem talking to the service")  
  25.   
  26.   return {  
  27.     "service"self.service_name,  
  28.     "token": token,  
  29.     "secret": secret  
  30.   }  


Twitterからもらえるuser_infoは↓のかんじ
  1. def _lookup_user_info(self, access_token, access_secret):  
  2.   """Lookup User Info. 
  3.  
  4.   Lookup the user on Twitter. 
  5.   """  
  6.   
  7.   response = self.make_request(  
  8.       "http://twitter.com/account/verify_credentials.json",  
  9.       token=access_token, secret=access_secret, protected=True)  
  10.   
  11.   data = json.loads(response.content)  
  12.   
  13.   user_info = self._get_default_user_info()  
  14.   user_info["id"] = data["id"]  
  15.   user_info["username"] = data["screen_name"]  
  16.   user_info["name"] = data["name"]  
  17.   user_info["picture"] = data["profile_image_url"]  
  18.   
  19.   return user_info  

2010年10月17日日曜日

phpを始める

phpを始める。
目指せ!phpの資格!!

apacheのダウンロード
Windowsで開発します
apache windows binary [Download]

eclipseのダウンロード
開発環境はeclipse + pluginで。
pleiades eclipse 3.6 [Download]

参考書
やっぱオライリーでしょうか
プログラミングPHP 第2版

php
Windows用のphp
php5.3
php

2010年10月8日金曜日

jTemplatesを使ってみる

ajaxでの通信後、HTML表示が面倒だなーと思ってたら、↓を発見。
業界的には気づくの遅いか??

jTemplates

javascript内に書いたり、
HTMLコメントとして書いたり、
いろいろできるっぽいけど
テンプレートファイルに書き出すのがスマートっぽい。

テンプレートファイル


templateフォルダにsample.tplとか置いてみる。


  1. {#template MAIN}  
  2. <table id="dataTable" border="1">  
  3. <thead>  
  4.     <tr>  
  5.         <th>ID</th>  
  6.         <th>名前</th>  
  7.         <th>紹介</th>  
  8.     </tr>  
  9. </thead>  
  10. <tbody>  
  11. {#foreach $T as sample}  
  12.     <tr>  
  13.         <td>{$T.sample.id}</td>  
  14.         <td>{$T.sample.name}</td>  
  15.         <td>{$T.sample.article}</td>  
  16.     </tr>  
  17. {#/for}  
  18. </tbody>  
  19. </table>  
  20. {#/template MAIN}  



JavaScript


jqueryと一緒に読み込んで、$(document).readyで書いてみる。
ちなみにjqueryは1.4.2


  1. <script charset="utf-8" type="text/javascript" src="/javascripts/jquery-1.4.2.min.js"></script>  
  2. <script charset="utf-8" type="text/javascript" src="/javascripts/jquery-jtemplates.js"></script>  
  3. <script type="text/javascript">  
  4.         $(document).ready(function() {  
  5.   
  6.             var datas = new Array();  
  7.             var data1 = {id:1, name:"IS03",   article:"ワンセグ、お財布ケータイ機能を持ったauのandroid"};  
  8.             var data2 = {id:2, name:"iphone", article:"Apple社の大人気スマートフォン"};  
  9.             var data3 = {id:3, name:"Xperia", article:"sony ericsson(docomo)のandroid"};  
  10.             var data4 = {id:4, name:"garaxy", article:"Samsung社製(docomo)のandroid"};  
  11.   
  12.             datas.push(data1);  
  13.             datas.push(data2);  
  14.             datas.push(data3);  
  15.             datas.push(data4);  
  16.   
  17.                 $("#result").setTemplateURL("/templates/sample.tpl");  
  18.                 $("#result").processTemplate(datas);  
  19.   
  20.         });  
  21.     </script>  




なんとまあ便利なんだろうか!!

2010年9月26日日曜日

GAE -テキストファイル出力-

↓のかんじ。
入力内容をファイルで出力するだけ。

ローカルだと日本語ファイル名できたけど、
デプロイしたらNGっぽくなった、、、、


  1. 'attachment;filename="' + filename.encode('utf-8') + '"'  


ここがNGなんだと思うけど、
文字コードは何にすればいいのか??




  1. class TextDownload(webapp.RequestHandler):  
  2.   def post(self):  
  3.     if users.get_current_user():  
  4.       url = users.create_logout_url(self.request.uri)  
  5.       url_linktext = 'Logout'  
  6.       login = True  
  7.       user_name = users.get_current_user().nickname()  
  8.     else:  
  9.       url = users.create_login_url(self.request.uri)  
  10.       url_linktext = 'Login'  
  11.       login = False  
  12.       user_name = 'anonymous'  
  13.   
  14.     text = self.request.get('filebody')  
  15.     filename = self.request.get('filename')  
  16.     if filename == '':  
  17.       filename = 'notitle.txt'  
  18.   
  19.     self.response.headers['content-type'] = "application/octet-stream; charset=utf-8"  
  20.     self.response.headers['Content-disposition'] = 'attachment;filename="' + filename.encode('utf-8') + '"'  
  21.     self.response.out.write(cgi.escape(text))  

2010年9月24日金曜日

デザインに凝ってみた

特に中身を変更したわけではないですが、テンプレートの使い方とか
pythonでのTrue, Falseとか覚えました。

Trueって書かないと駄目なんですね。
trueじゃ。

あと、

!変数

もだめで、

not 変数

なんですね。
勉強になります。

2010年9月23日木曜日

GAE メール送信成功!

GAEのサンプルにあるguestbookにメール送信機能をつけてみた。

●機能


ログインして書き込むとログインしているユーザ宛てに書き込んだ内容が送信される


使ってみたけど、結構無駄機能?
量が多いとちょっとウザイかも。

↓こんなかんじ
  1. if users.get_current_user():  
  2.     sender_address = users.get_current_user().email()  
  3.     subject = "GuestBook is Updated"  
  4.     body = "[%s] %s" % (greeting.date, self.request.get('content'))  
  5.     mail.send_mail(sender_address, greeting.author.email(), subject, body)  

gae and python at eclipse

まず、python2.5をアップデートしました。
2.5.2 → 2.5.4

2.5.4

インストールしたら、なぜか2.5.2が消えました。

!!!

続いてpydevは、updateサイトだとエラーが出てしまったので
仕方なくzipを解凍して置きました。

 pydev at sourceforge


インストール終わったので、eclipse起動。

新規→「その他」→「PyDev Google App Engine Project」

でプロジェクト作成。

pythonは忘れずにインストールした2.5.4を指定。

さて、これから頑張ってみます。

GAE再び

Androidアプリを作るにしても
Webサービスとの連携しなくては!と思ったので
GAE再開です。

Javaプログラマですが、
ここは何とかPythonでやってみようと思います。


ユーザーサービスの利用


pythonを複数バージョン入れてたらエラーが出だした、、、



pythonを2.5だけにして2.7をアンインストールしたら動いた。
環境変数指定してるのに不思議だなー

2010年9月6日月曜日

オライリーで頑張ってます|3章

オライリーの本買って、それで勉強してます。
「初めてのandoroid」


今日までで、aboutの表示まで完成しました。

まずは初期画面。
一応、日本語にしてみました。





でで、ヘルプっていうのを押したときの画面も。




ヘルプの内容を訳すのが面倒だった、、、、

2010年9月4日土曜日

Android SDK with Xperia

そにーえりくそんのページから
Xperiaのskinを入手できる。

いま一番のandroidインJAPANなので
これで作りたいと思い、以下のページから入手

ここから入手


ログインが必要ということでしたが、
アカウントなくても入手できました!!

ダウンロードしたファイル「102216-XPERIA-X10_SDK_Add-on_r1.zip」
を解凍して出てきたフォルダ「XPERIA-X10_r1」を丸ごと移動。

移動先は、androidをインストールした場所のadd-onsフォルダ内。
私はandroidを「C:\opt\android\android-sdk-windows」に入れたので、

「C:\opt\android\android-sdk-windows\add-ons」に入れて
「C:\opt\android\android-sdk-windows\add-ons\XPERIA-X10_r1」
となりました。

あとは、Eclipseだと楽勝ですね。

Window→Android SDK and AVD Manager→Virtual Devices

新規(New)から

名前はXperia
ターゲットはX10(Sony Ericsson Mobile Communications)
SDカードは100でいいかな

2010年8月12日木曜日

python

いろいろと言語を勉強してみたくなった。
まずはPHPと思ったけど
早速Pythonに変更!

●開発環境はeclipse with pydev




●python自体は公式サイトからWindows版インストーラをゲット



このファイルをゲットしました → python-2.7.msi

●インストール場所は

C:\usr\local\python

にバージョンごとに入れることにしました。
↓こんなかんじ

C:\usr\local\python\python27\

●ついでにjythonもゲット
↓から、jython_installer-2.5.1.jarをゲット




例によって、C:\usr\local\jythonに入れます。


eclipseを起動して、設定からPydevのインタープリタを今回入れたものにしました。
最初からpython入ってるけど、それは削除。
バージョンわからんし。

2010年6月29日火曜日

Android SDK

Android SDKを入れてみた。

1. ダウンロード

<http://developer.android.com/sdk/index.html> からダウンロードしました。
android-sdk_r06-windows.zip です。

2. 解凍

上記zipを解凍して、C:\opt\android\android-sdk-windows としました。

3. パスの設定

ANDROID_HOME=C:\opt\android\android-sdk-windowsとして、
Pathに%ANDROID_HOME%\tools を追加しました。

4. インストール

C:\opt\android\android-sdk-windows にあるSDK Setup.exeをダブルクリックするが、


Failed to fetch URL https://dl-ssl.google.com/android/repository/repository.xml,
reason: HTTPS SSL error.
You might want to force download through HTTP in the settings.


とか出るので、以下を実施
C:\opt\android\android-sdk-windows\tools に.androidフォルダが出来ているので、
そこにandroidtool.cfg というファイルを作って、


sdkman.force.http=true


と書きます。
んで、再チャレンジ!



2010年4月2日金曜日

Seleniumの証跡をHTMLソースで

Selenium好きです。

でも、まあ、画面証跡だとdiffを取るのが難しいですよね。

で、HTMLで証跡を取りたいのですが、

なかなか難しい。

拡張スクリプトでも作ろうかと思いましたが、

JavaScriptでの保存は難しかった。

そこで、アドオンを利用することを思いついた。
以下のサイトの応用を考えたのです!

[Test]Seleniumでキャプチャを取得する拡張コマンド:captureScreenshot


つまり、HTMLを取得するアドオンをインストールし、
ショートカットキーを使えばいいと。


で、ありました。

ScrapBook


これ入れると、

Ctrl + Shift + L


でHTMLを保存できます。

Selenium的には、以下のコマンドを挿入すれば大丈夫です。
ポイントはshiftKeyUpとcontrolKeyUpです。

★これをやらないと、typeコマンドでエラーがでてしまいます。


<tr>
    <td>controlKeyDown</td>
    <td></td>
    <td></td>
</tr>
<tr>
    <td>shiftKeyDown</td>
    <td></td>
    <td></td>
</tr>
<tr>
    <td>keyPress</td>
    <td>//body</td>
    <td>76</td>
</tr>
<tr>
    <td>controlKeyUp</td>
    <td></td>
    <td></td>
</tr>
<tr>
    <td>shiftKeyUp</td>
    <td></td>
    <td></td>
</tr>


で、最後にScrapBookの設定です。

ツールバーにある「ScrapBook」から「サイドバーに表示」をクリックし、
「ツール」→「設定」→「詳細」から
”取り込みが完了したら通知する”をOFFにしてください。


あと問題なのは、全HTMLファイル、画像等を取得してくれるのですが、
ファイル名が全部index.htmlであることでしょうか。。。



以上でございます。

2010年4月1日木曜日

続いて

Rubyの思想とか、
だいたいの文法とか勉強しました。

で、あまり向いてなさそうだったので、
もうしばらくJavaで行こうと思います。

そんで、以下のものに手を出しました。


  1. play!

  2. mayaa



play!はRuby on Railsの思想で簡単構築を目指したので。

mayaaはJSP嫌いなので。
JSPとも親和性あるので、他よりは導入が気楽そう。
(他が何を指すか不明ですが。。。)

2010年2月27日土曜日

Ruby: 線形探索法組んでみた

線形探索法をRubyで実装してみた。
配列[5, 2, 1, 3, 4]からanswer=3を探索するプログラム。
if文の書き方に手間取った。
あと、型を書かなくていいってことに戸惑った。
whileじゃなくて、eachとかでも良かったのかな?
繰り返しの実装方法も慣れない。

〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
array = [5, 2, 1, 3, 4];

index = 0;
answer = 3;
array[5] = 1;

while index < array.length
if array[index] == answer then
break
else
index = index + 1
end
end

if index < array.length - 1 then
print "success, answer=array[", index, "]:", array[index]
else
print "failure";
end
〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓

2010年2月10日水曜日

Ruby

Ruby始めました。

2010年1月30日土曜日

ウィンドウ名の取得

あんまり使わないと思ってたけど
意外と使う機会があった。
ウィンドウ名の取得

  1. <script language="Javascript" type="text/javascript"><!--  
  2. $(document).ready(function() {   
  3.   
  4.     if (window.name!="hoge") {  
  5.         $('input').each(function(){  
  6.             $(this).attr('disabled''true');  
  7.         });  
  8.           
  9.         $('#main').css('visibility''hidden');  
  10.     }  
  11. });   
  12. //--></script>  



メインウィンドウでない場合は、サイズを変えたいとか。
まあ、画面の使いまわし。
そういうの好きじゃないけど、
最後の最後ってとこで使えそう。

2010年1月15日金曜日