PythonのBottleフレームワークで静的ファイルのリンク生成

Bottleフレームワークを触ってみてます。
Pythonの軽量Webフレームワーク「Bottle」

上記で作成したサンプルに画像を表示しようとした時事件が・・・



よくある問題



staticというフォルダを作成し、image.jpgを保存。
それを表示しようと、こんなプログラムとテンプレートを作成しました。


index.py


  1. # -*- coding:utf-8 -*-
  2. from bottle import route, run, view, static_file
  3. @route('/static/<filepath:path>')
  4. def static(filepath):
  5.     return static_file(filepath, root="./static")
  6. @route('/<name>/<count:int>')
  7. @view("hello_template")
  8. def hello(name, count):
  9.     return dict(name=name, count=count)
  10. run(host='localhost', port=8080, debug=True, reloader=True)




hello_template.tpl


こんにちは。<b>{{name}}</b>さん。<br />
<br />
{{count}}回ループするよ<br />
<br />

% for i in xrange(count):
{{i}}回<br />
% end

<img src="./static/image.jpg">




これだと、画像は表示されません。

160_01.png


最初よくわからなかったのですが、冷静に考えれば当たり前で

表示しているURL
http://localhost:8080/symfoware/1

./static/image.jpgはフルのURLに直すと
http://localhost:8080/symfoware/static/image.jpg

狙っているURLは
http://localhost:8080/static/image.jpg

そりゃ表示されません。

じゃあ、../../static/image.jpgにすればいいんですけど、そういう問題でもないし。





解決方法



ここがヒントになりました。

Static files not loaded in a Bottle application when the trailing slash is omitted

若干Bottleのバージョンが古いようで、そのままでは動きませんでしたが、
要するにget_urlっていうメソッドがあるから、それを使えばいい感じになると。

ただ、get_urlはテンプレートじゃ使えないから関数をパラメーターとして渡してね。
という感じです。


Bottle ver0.11で動かしたコードはこんな感じ。

index.py


  1. from bottle import route, run, view, static_file, url
  2. @route('/static/<filepath:path>', name='static_file')
  3. def static(filepath):
  4.     return static_file(filepath, root="./static")
  5. @route('/<name>/<count:int>')
  6. @view("hello_template")
  7. def hello(name, count):
  8.     return dict(name=name, count=count, url=url)
  9. run(host='localhost', port=8080, debug=True, reloader=True)




hello_template.tpl


こんにちは。<b>{{name}}</b>さん。<br />
<br />
{{count}}回ループするよ<br />
<br />

% for i in xrange(count):
{{i}}回<br />
% end

<img src="{{url('static_file', filepath="image.jpg")}}">





まず、get_urlはBottleクラスに移動されていました。
しかし、ソースを見ると


  1. def make_default_app_wrapper(name):
  2.     ''' Return a callable that relays calls to the current default app. '''
  3.     @functools.wraps(getattr(Bottle, name))
  4.     def wrapper(*a, **ka):
  5.         return getattr(app(), name)(*a, **ka)
  6.     return wrapper
  7. # (略)
  8. url     = make_default_app_wrapper('get_url')



こんな感じで、urlとしてラップされていますので、「url」を使用します。

また、@routeは「name」で名前をつけることができます。
このnameで指定した名称で、urlメソッドから変換したいurlのポイントを指定します。


urlメソッドの引数は、

url(@routeで指定したname, [引数の名称] = "値")




こんなイメージです。

160_02.png



ソースを修正して表示してみると、見事画像が表示されました。

160_03.png



これ、画像以外のcssやjsでも発生する問題だと思います。
解決できてよかった。

関連記事

コメント

非公開コメント

プロフィール

Author:symfo
blog形式だと探しにくいので、まとめサイト作成中です。
Symfoware まとめ

PR




検索フォーム

月別アーカイブ