今週、etpl ノード ラッパーを npm に送信し、対応する github アドレス: https://github.com/wslx520/etpl-wrap
etpl は私が使用した非常に強力なテンプレート エンジンで、必要な機能がすべて備わっています。
etplはnode環境でも使えますが、使い方が想像と違いました。
これは私が koa を学ぶことから始まりました。私が学んだ koa2 には、テンプレート ファイルをレンダリングする機能にアクセスするために使用される koa-views ミドルウェアがあります。ただし、当然ながら etpl と併用することはできません。
以前の Express にも同じことが当てはまりました。エンジンが Express と連携したい場合は、追加の設定が必要であり、おそらくソース コードで何らかの特別な作業を行う必要があります。
これは非常に厄介だと思いますが、Web フレームワークはテンプレート エンジンと大きく関係していますか?それらは互いに独立すべきではないでしょうか?
たとえば、koa は koa-views を使用し、テンプレート エンジンに接続されているため、テンプレートをレンダリングするときに
ctx.body = ctx.render('index', data) を使用できます。 )
は次のような構文を使用してレンダリングされます。しかし、完全に独立したテンプレート エンジンがあれば、このように使用できるのではないかと考えました。 :
ctx.body = etpl.render(‘index’,data)
この使用法では、テンプレート エンジンは Web フレームワークとは何の関係もありません。同じ構文を Express でも使用できます:
res.end(etpl.render(‘index’,data))
これはより良い状態ではないでしょうか?テンプレート エンジンを Web フレームワークに挿入する必要があるのはなぜですか?
Node もサーバー環境です。テンプレート ファイルがある場合、それは通常ファイルです。しかし、etpl にはファイルを直接レンダリングする機能がありません。
etpl を使用して Node でテンプレート ファイルをレンダリングする場合、通常のプロセスに従って、最初にファイルの内容を読み取り、それを文字列に変換し、それを etpl.compile に渡す必要があります。次にレンダリングします。
しかし、これはあまりにも愚かで、受け入れることができません。
そこで、node.js で etpl を便利に使用するために、このようなラッパーを書きたいと思います。
ラッパーには原則があります: 変更できない 原文ソースコード。つまり、etpl 自体には何もできません。そうしないと、将来 etpl をアップグレードすることが困難になります。
etplのソースコードをざっと見てみましたが、複雑で時間も限られているので読むのは現実的ではありません(実はよく理解していません)
当初は、レンダリング時に、対応するテンプレート ファイルがコンパイルされていない場合は動的に読み取り、コンパイルしてからレンダリングし、コンパイル結果をキャッシュすることを計画していました (コンパイルを繰り返すコストを回避するため)。
しかし、これは少し難しく、etpl ソース コードを変更する必要があるかもしれません。
後で私は自分を慰め、Web サイトのテンプレート ファイルの合計は 10M を超えてはいけないと言いました。小規模な場合ですが、アクセスして etpl.compile を呼び出した瞬間からすべてのテンプレート ファイルを順番に読み込んでいきました。それらをコンパイルしておけば、今後 etpl.render を使用するときに「コンパイルされているかどうか」を心配する必要はありません。
これにより、サーバーの起動時に追加の消費が確実に発生しますが、許容できるはずです。
etpl は、さまざまな「モジュール」のコンパイルを容易にするために target を使用します。たとえば、新しいテンプレート ファイルindex.html を作成し、将来 etpl.render('index',data) を実行したい場合、index.html の最初の文は次のようなターゲット ステートメントである必要があります。 !– target:index –>
しかし、サーバー側ではそれぞれの異なるファイルが異なるモジュールであるため、これはサーバー側にとって明らかに不合理です。
ラッパーは次のような処理を行います:
テンプレート ファイルの最初の文がターゲット ステートメントではない場合、現在のテンプレート ファイルの名前がターゲット名として使用されます。
また、テンプレート ファイルの最初の文でターゲットを宣言する必要がある場合、ターゲット名はテンプレート ファイルと一致している必要がありますname
それはまだ当てはまります ターゲットを書かない方が費用対効果が高いです
さらに、ブラウザ側では、ユーザーは同じ名前のターゲット名の問題を回避する必要があります。ただし、サーバー側では、ルート ディレクトリまたはサブディレクトリに list.html が存在する可能性があります。理論的には、サブディレクトリ内の 2 つの
2016/ の間に競合はありません。 5 月 5 日の午後、「同じディレクトリ内のすべてのターゲットは同じレベルである」という原則を理解するために。この原則に基づいて、サブディレクトリ内のテンプレートの問題の多くは簡単に解決できると思います。
サブディレクトリに複数のテンプレート ファイルがある場合、インデックスがメインのファイルになります。デフォルトのドキュメント。サブディレクトリ: main がある場合、その下のインデックスは自動的に target:main
になります。このとき main/index を参照したい場合は、main を参照するだけです。
、main/content などの他のファイルがターゲットになります: main/content
しかし、実際には、main と main/content は同じレベルにあります (main=main/index であるため)
インデックス、メインなどに設定できる「デフォルトのメイン テンプレート」パラメータ を追加することを 検討できます。
サーバー環境のテンプレートには別の問題があります。それは、サブディレクトリ内のテンプレートです。
たとえば、ルート ディレクトリのindex.html は次のようにインポートできます: list/list1.html
サブディレクトリ内のテンプレートは、次のように親ディレクトリ内のテンプレートを参照することもあります。 import: ../header
これは、ブラウザ側の etpl では発生しない状況です
幸いなことに、 がターゲット名をパスとして直接取得する場合、 は次のように etpl でも通常に使用できます。
target: header/head-detail
もちろん、etpl では 1 つのテンプレート ファイルで複数のターゲットが許可されているため、この関数を削除することはできません
次に、テンプレート ファイル内で、他のターゲットはインポートされていますか? この時点で、
はこのファイルの別のターゲットへの参照ですか?
はこのファイルの同じレベルにある他のテンプレート ファイルへの参照です。 ?
参照先が同じレベルまたは親レベルの他のテンプレート ファイルに存在する場合、優先順位は何ですか? – このファイルには最も高い
があり、最も単純な原則によれば、優先順位は次のようになります: 同じファイルの下のターゲット==> 同じレベルの下の他のファイルのターゲット
たとえば、header.html がありますが、デフォルトでは target:header とみなされますが、その後ろに別のターゲット li があります。この時点では、別のテンプレート ファイル リストがあります。 .html も使用したいのですが、これを引用するにはどうすればよいですか?
当初、インポート時に import: header.li を使用してインポートすることを検討していましたが、テストの結果、そのようなターゲット名が原因で etpl がエラーを報告することがわかりました (後でソースコードを確認すると、この問題は次のように修正できます)ソースコードですが、これは私には合いません 要件)
この参照が許可されている場合、次のことが発生する可能性があります: import: head/head-left/logo.image 状況
モジュール ファイルからのインポートを一時的に無効にする予定です。他のテンプレート ファイルからメイン以外のターゲットを導入します。 (ただし、メインではないターゲットに競合しない名前を付ける人もいると思います。また、他のテンプレート ファイルはグローバル ターゲットとして参照されるでしょう。これは合法であるべきであり、禁止されるべきではありません)
2016/ 5 /5:
今日アイデアを思いつきました。同じファイル内に複数のターゲットがある場合、メイン ターゲット以外のターゲットはメイン ターゲットのサブターゲットとして扱われます。例: メイン ターゲット: main、このファイル内の他のターゲットは main/li、main/p などです。この方法では、それらを参照したい外部ファイルがある場合は、次のように直接インポートできます: main/li
ただし、次の要件があります: すべてのテンプレート ファイルのすべてのターゲットが同じレベルのディレクトリに同じ名前 を付けることはできません。しかし、それは可能です。
午後、別の質問が頭に浮かびました:
たとえば、サブディレクトリ main の下にあるメイン テンプレート ファイル インデックスに他のターゲット: Good が含まれている場合、ターゲット: main/ にコンパイルされます。コンパイル中は良好です
メイン ディレクトリに別のテンプレート ファイル content.html があり、これには他のターゲットもあります。このとき、main/content/other または main/other にコンパイルする必要がありますか?
ターゲットが他のサブテンプレートで宣言されている場合でも、「同じディレクトリ内のすべてのターゲットが同じレベル」であることを確認する必要があるため、一時的に後者であると決定しました。 files
ノードにはディレクトリの概念があるため、ターゲットにもパスがあります。ブラウザのように import:target1、import:target2 になることはありません。 : import:list/li1, import:list/li2, import:../main/list2
ただし、前述したように、ターゲットに出現すると etpl がエラーを報告することになります
ラッパーでは、../ のような相対パスは、 テンプレートのルート ディレクトリ から始まる絶対パスに変換されます。たとえば、root/main/list/ul.html テンプレート ファイル import:../list2/li は次のように変換されます: import:/main/list2/li
fn.call のような関数の実行効率は数分の 1 に低下するため、
の実行に call を使用することを避けるために、追加のパラメーターがいくつかの関数に追加されます。