アプリケーション構造
まず、プロジェクトの標準ディレクトリ構造について説明します。 CherryPyには必須ではないため、使用するデータレイヤ、フォーム検証、テンプレートエンジンなどは教えられません。それはあなたとあなたの要求に依存します。もちろん、初心者には混乱を招くので、これは大きな柔軟性です。実際のアプリケーションのディレクトリ構造に近いように見えます。
そして、あなたは通常、開発環境でCherryPyはを起動するには、次のん
virtual environmentのルートに立っ
. — Python virtual environment
└── website — cherryd to add this to sys.path, -P switch
├── application
│ ├── controller.py — request routing, model use
│ ├── model.py — data access, domain logic
│ ├── view — template
│ │ ├── layout
│ │ ├── page
│ │ └── part
│ └── __init__.py — application bootstrap
├── public
│ └── resource — static
│ ├── css
│ ├── image
│ └── js
├── config.py — configuration, environments
└── serve.py — bootstrap call, cherryd to import this, -i switch
。 cherryd
はCherryPyが提案するアプリケーションの実行方法です。
. bin/activate
cherryd -i serve -P website
テンプレート化
今度は、テンプレートディレクトリに近づくとそれがどのように見えることができます見てみましょう。ここでは、template inheritanceの素敵なJinja2のの機能を利用するには
.
├── layout
│ └── main.html
├── page
│ ├── index
│ │ └── index.html
│ ├── news
│ │ ├── list.html
│ │ └── show.html
│ ├── user
│ │ └── profile.html
│ └── error.html
└── part
└── menu.html
は、ページの構造を定義するレイアウト、特定のページに充填することができるスロットです。ウェブサイトのレイアウトとメール通知のレイアウトがあるかもしれません。また、別のページにまたがって使用される再利用可能なスニペットもあります。上の構造に対応するコードを見てみましょう。
a runnableというファイルをナビゲートする方が簡単で、実行して再生することもできます。パスは、最初のセクションのツリーのように.
で始まります。
ウェブサイト/ config.py
# -*- coding: utf-8 -*-
import os
path = os.path.abspath(os.path.dirname(__file__))
config = {
'global' : {
'server.socket_host' : '127.0.0.1',
'server.socket_port' : 8080,
'server.thread_pool' : 8,
'engine.autoreload.on' : False,
'tools.trailing_slash.on' : False
},
'/resource' : {
'tools.staticdir.on' : True,
'tools.staticdir.dir' : os.path.join(path, 'public', 'resource')
}
}
ウェブサイト/ serve.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from application import bootstrap
bootstrap()
# debugging purpose, e.g. run with PyDev debugger
if __name__ == '__main__':
import cherrypy
cherrypy.engine.signals.subscribe()
cherrypy.engine.start()
cherrypy.engine.block()
Webサイト/アプリケーション/ __ init__.py
ここ
注目すべき部分がありますCherryPyツールは、レンダリングに関連する定型句を避けるのに役立ちますgテンプレート。 CherryPyページハンドラーからdict
をテンプレートのデータとともに返すだけでいいです。従来の構成上の原則に従うと、ツール名は、classname/methodname.html
などを使用します。 user/profile.html
。デフォルトのテンプレートを上書きするには、@cherrypy.tools.template(name = 'other/name')
を使用します。あなたはツールを使用して見ることができるように、トップ
# -*- coding: utf-8 -*-
import os
import types
import cherrypy
import jinja2
import config
class TemplateTool(cherrypy.Tool):
_engine = None
'''Jinja environment instance'''
def __init__(self):
viewLoader = jinja2.FileSystemLoader(os.path.join(config.path, 'application', 'view'))
self._engine = jinja2.Environment(loader = viewLoader)
cherrypy.Tool.__init__(self, 'before_handler', self.render)
def __call__(self, *args, **kwargs):
if args and isinstance(args[0], (types.FunctionType, types.MethodType)):
# @template
args[0].exposed = True
return cherrypy.Tool.__call__(self, **kwargs)(args[0])
else:
# @template()
def wrap(f):
f.exposed = True
return cherrypy.Tool.__call__(self, *args, **kwargs)(f)
return wrap
def render(self, name = None):
cherrypy.request.config['template'] = name
handler = cherrypy.serving.request.handler
def wrap(*args, **kwargs):
return self._render(handler, *args, **kwargs)
cherrypy.serving.request.handler = wrap
def _render(self, handler, *args, **kwargs):
template = cherrypy.request.config['template']
if not template:
parts = []
if hasattr(handler.callable, '__self__'):
parts.append(handler.callable.__self__.__class__.__name__.lower())
if hasattr(handler.callable, '__name__'):
parts.append(handler.callable.__name__.lower())
template = '/'.join(parts)
data = handler(*args, **kwargs) or {}
renderer = self._engine.get_template('page/{0}.html'.format(template))
return renderer.render(**data) if template and isinstance(data, dict) else data
def bootstrap():
cherrypy.tools.template = TemplateTool()
cherrypy.config.update(config.config)
import controller
cherrypy.config.update({'error_page.default': controller.errorPage})
cherrypy.tree.mount(controller.Index(), '/', config.config)
Webサイト/アプリケーション/ controller.py
に@cherrypy.expose
を追加する必要はありませんので、また、ツールが自動的にメソッドを公開することに注意してくださいページハンドラはきれいに見え、他のツールと一貫性があります。 json_out
。このデモアプリケーションで
# -*- coding: utf-8 -*-
import datetime
import cherrypy
class Index:
news = None
user = None
def __init__(self):
self.news = News()
self.user = User()
@cherrypy.tools.template
def index(self):
pass
@cherrypy.expose
def broken(self):
raise RuntimeError('Pretend something has broken')
class User:
@cherrypy.tools.template
def profile(self):
pass
class News:
_list = [
{'id': 0, 'date': datetime.datetime(2014, 11, 16), 'title': 'Bar', 'text': 'Lorem ipsum'},
{'id': 1, 'date': datetime.datetime(2014, 11, 17), 'title': 'Foo', 'text': 'Ipsum lorem'}
]
@cherrypy.tools.template
def list(self):
return {'list': self._list}
@cherrypy.tools.template
def show(self, id):
return {'item': self._list[int(id)]}
def errorPage(status, message, **kwargs):
return cherrypy.tools.template._engine.get_template('page/error.html').render()
私は作品を扱う方法を静的リソースを証明するために、blueprint CSSファイルを使用していました。 website/application/public/resource/css/blueprint.css
に入れてください。残りはあまり面白くなく、ちょうどJinja2が完全性のためのテンプレートです。
Webサイト/アプリケーション/ビュー/レイアウト/ main.htmlを
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='content-type' content='text/html; charset=utf-8' />
<title>CherryPy Application Demo</title>
<link rel='stylesheet' media='screen' href='/resource/css/blueprint.css' />
</head>
<body>
<div class='container'>
<div class='header span-24'>
{% include 'part/menu.html' %}
</div>
<div class='span-24'>{% block content %}{% endblock %}</div>
</div>
</body>
</html>
Webサイト/アプリケーション/ビュー/ページ/インデックス/インデックス。HTML
{% extends 'layout/main.html' %}
{% block content %}
<div class='span-18 last'>
<p>Root page</p>
</div>
{% endblock %}
Webサイト/アプリケーション/ビュー/ページ/ニュース/するlist.html
{% extends 'layout/main.html' %}
{% block content %}
<div class='span-20 last prepend-top'>
<h1>News</h1>
<ul>
{% for item in list %}
<li><a href='/news/show/{{ item.id }}'>{{ item.title }}</a> ({{ item.date }})</li>
{% endfor %}
</ul>
</div>
{% endblock %}
Webサイト/アプリケーション/ビュー/ページ/ニュース/ show.html
{% extends 'layout/main.html' %}
{% block content %}
<div class='span-20 last prepend-top'>
<h2>{{ item.title }}</h2>
<div class='span-5 last'>{{ item.date }}</div>
<div class='span-19 last'>{{ item.text }}</div>
</div>
{% endblock %}
ウェブサイト/アプリケーション/表示/ページ/ユーザー/ profile.html
{% extends 'layout/main.html' %}
{% block content %}
<div class='span-18'>
<table>
<tr><td>First name:</td><td>John</td></tr>
<tr><td>Last name:</td><td>Doe</td></tr>
<table>
</div>
{% endblock %}
Webサイト/アプリケーション/ビュー/ページ/ error.html
それは404ページです。
{% extends 'layout/main.html' %}
{% block content %}
<h1>Error has happened</h1>
{% endblock %}
Webサイト/アプリケーション/ビュー/パート/ menu.html
<div class='span-4 prepend-top'>
<h2><a href='/'>Website</a></h2>
</div>
<div class='span-20 prepend-top last'>
<ul>
<li><a href='/news/list'>News</a></li>
<li><a href='/user/profile'>Profile</a></li>
<li><a href='/broken'>Broken</a></li>
</ul>
</div>
参照
上記のコードはqooxdoo-website-skeletonのバックエンド部分と密接に行きます。このようなアプリケーションのDebain展開を本格的に行うには、cherrypy-webapp-skeletonが便利です。
私は問題のあるプロジェクトの構造も分かりませんでした。この記事とリンクは、少し物事を明確にするのに役立ちました。 https://groups.google.com/forum/?fromgroups#!topic/cherrypy-users/L7YXZD_55ec –
ニース!この紹介は、私がCherryPyとMakoを開始するのに十分です。 –
Upvoteしかし、私の問題はNginx http://stackoverflow.com/questions/23359095/how-to-put-cherrypy-wsgi-behind-nginxで続けるので、助けてください。 – Alex