Django DIYパート1:jinja2のテンプレートの作成

はじめに



この投稿では、djangoのようなプラグインシステムを使用した小さなフレームワークの作成について説明したいと思います。 外部コンポーネントのみを使用します。 テンプレートにはJinja2、環境変数にはボトル、pymongoがORMの代わりに使用され、ビーカーがセッションに参加します。

最初のパートでは、Jinja2を接続して、さまざまなフォルダーからテンプレートを組み立て(プラグインを読み取る)、それらをキャッシュできることの便利さを伝えたいと思います。

また、次のパートでは、gettextをテンプレートに接続し、翻訳を自動化する方法を説明したいと思います。



フレームワーク構造



ライブラリとしてのフレームワークは、ubuntu '/usr/local/lib/python2.6/dist-packages/'の可能性が最も高い任意のディレクトリにあり、プロジェクトの場所はどこでも、たとえば '/ home / user / worckspace / '。 プロジェクトにはmod_wsgiまたはuwsgi index_wsgi.pyのindex.wsgiがあり、ライブラリに手動でコピーされた場合、ライブラリへのパスが表示されます。

プロジェクトの構造は次のとおりです。

/project/ /__init__.py /app/ /__init__.py /app1/ /__init__.py /templ/ /static/ /routes.py /models.py /views.py /teml/ /static/ /index.py /routes.py /views.py /models.py /settings.py
      
      





したがって、/ templサブディレクトリには、/ static statics、/ appに任意の数のアプリケーション(または必要に応じてコンポーネント)にテンプレートがあります。

したがって、ライブラリにはdjang contribの類似物であるappフォルダーもあり、その中にテンプレートを持つコンポーネントも存在すると想定されています。

沈黙プロジェクトにもフォルダーが作成されます。たとえば、そのフォルダー内のキャッシュは、jinja2がテンプレートキャッシュを保存します。



接続テンプレート



したがって、すべての接続はコアパッケージのcore.pyファイルにあり、core.pyファイルはライブラリのルートにあります。 必要なクラスをインポートします。

 from jinja2 import Environment, PackageLoader, FunctionLoader, FileSystemBytecodeCache
      
      





次に、テンプレートのパスを決定します。テンプレートをロードするときにこの関数を呼び出します。

選択するテンプレートには、いくつかの拡張子を付けることができます。

 def get_app_root(app): """Returns path to app or app name.""" if isinstance(app, (str, )): __import__(app) app = sys.modules[app] return os.path.dirname(os.path.abspath(app.__file__)) templ_exts = ['', '.tpl', '.html', '.htm'] def split_templ_name (t): """     .            .       . """ if ':' in t: #        module, file = t.split(":", 1) module_path = os.path.join(get_app_root( module), "templ", "") else: #        . module = ' ' module_path = os.sep + 'templ' + os.sep file = t return (module, module_path, file)
      
      





実際にテンプレートをロードします。

ここでは、たとえばデータベースからロードすることにより、代替のテンプレート保存場所を実装できます

 def union_templ(t, **p): (module, module_path, file) = split_templ_name (t) def load_template (base, module_path, file): path = base + module_path + file template = ' ' for ext in templ_exts: filename = path+ext if os.path.exists(filename): with open(filename, "rb") as f: template = f.read() break; return template template = load_template (os.getcwd(), module_path, file); if not template: template = load_template( settings.lib_path, module_path, file); if not template: return 'Template not found %s' % t return template.decode('UTF-8')
      
      







テンプレートをキャッシュするためのフォルダーを自動的に作成します。

 jcp = os.path.join(os.getcwd(), 'jinja_cache') if not os.path.isdir(jcp): os.mkdir(jcp)
      
      







キャッシュ管理オブジェクトを作成します。

 bcc = FileSystemBytecodeCache(jcp, '%s.cache')
      
      







jinja2にフックを掛け、キャッシュの必要性を示し、テンプレートをロードするために呼び出す必要のある関数を渡します。



 jinja = Environment(auto_reload=True, loader=FunctionLoader(union_templ), bytecode_cache = bcc )
      
      







テンプレートのレンダリングを直接実行する関数。 現在、彼女は特別なことを何もしておらず、直接jinja2に制御を移していますが、ここに戻ります。

 def render_templ(t, **p): template = jinja.get_template(t) return template.render(**p)
      
      







この機能をグローバルレベルにインポートします。

 __builtin__.templ = render_templ
      
      







この最後の行のおかげで、任意のファイルでtempl()関数を呼び出して、引数にテンプレートの名前とそれに表示するものを渡すだけで十分です。 例:

return templ( 'app.base:base'、param = param)またはreturn templ( 'base'、param = param)、 ':'は、テンプレートがプロジェクト内ではなく、この場合は 'app.baseの対応するコンポーネント内にあることを意味します'。



まとめ



ですから、まず第一に、モジュール構造の小さなフレームワークがあります。 これに基づいて先に進みます。

これはまだ最初の記事であり、おそらくもっとよく書かれているはずなので、すべてのコメントと質問に喜んでいます。



継続



All Articles