Jadeテンプレートエンジンで実行されているnode.jsエクスプレスサーバーを持っています。
次のように、個々のビューの本体をインポートするレイアウトjadeファイルがあります。
!!!
html
head
title= title || 'Title not set.'
body
#header
h1 Header.
#content!= body //- this renders the body of an individual view
#footer
p Footer.
たとえば、次のインデックスページ:
p Welcome to the front page.
p This page serves as a now.js test.
これは正常に動作します。ただし、このインデックスページ専用に2つのクライアント側JavaScriptライブラリを含めたいと思っています(そのため、すべてのページではないため、レイアウトの先頭に配置できません)。
これは機能します:
//- import jquery
script(type='text/javascript', src='./jquery-1.5.2.min.js');
//- import now.js (hosts itself)
script(type='text/javascript', src='/nowjs/now.js')
//- import the chat client
script(type='text/javascript', src='./indexChatClient.js')
p Welcome to the front page.
p This page serves as a now.js test.
しかし、これはスクリプトをページ全体にロードしますが、これは有効なHTMLではありませんよね?
私の知る限り、スクリプトを適切に実行するには、スクリプトをヘッドにロードする必要がありますが、ヘッドセクションはレイアウトファイルによって処理されます。
では、特定のビュー/ページ専用にこれらのクライアント側のJavaScriptライブラリを適切に含めるにはどうすればよいでしょうか。
私はこのスレッドのソリューションを使用して同じことを行いました:
http://groups.google.com/group/express-js/browse_thread/thread/8c2006dc7bab37b1/f9a273c836e0a2ac
「スクリプト」変数をビューオプションに宣言できます。
app.js:
app.set('view options', { locals: { scripts: ['jquery.js'] } }); // You can declare the scripts that you will need to render in EVERY page
レイアウトのヘッドにスクリプトタグをレンダリングするヘルパーを持つことができるよりも
renderScriptTags()ヘルパーコード:
app.helpers({ renderScriptTags: function(scripts) {
return scripts.map(function(script) {
return '<script src="scripts/' + script + '"></script>';
}).join('\n ');
ヘッドセクションのレイアウトテンプレートには、次のものが含まれます。
- renderScriptTags(scripts)
次に、headタグにスクリプトを追加するには、翡翠コンテンツテンプレート(ボディテンプレート)の「scripts」変数にスクリプトをプッシュする必要があります。
- scripts.Push('myscript.js');
このようにして、ページはjquery.jsとmyscript.jsをページの先頭にレンダリングします
[〜#〜]更新[〜#〜]
最新の高速バージョンはローカルを別の方法で処理するようです、これを適切に機能させるには、これを行うことができます(ただし、これが最適なソリューションであるかどうかはわかりませんが、これを少し掘る必要があります)
以前と同じように、レイアウトテンプレートで前のメソッドのrenderScriptTags()ヘルパーを使用できます。
ただし、スクリプト変数をローカルに設定しないでください。代わりに、テンプレートでscripts変数を使用できるようにする動的ヘルパーを作成します。
app.dynamicHelpers({
scripts: function(req, res){
return ['jquery.js']; //this will be available in all views
}
});
次に、特定のスクリプトを本文テンプレートから追加するには(以前とまったく同じ):
- scripts.Push('myscript.js');
この特定のビューでは、jquery.jsとmyscript.jsを適切にレンダリングする必要があります
それらをレイアウトに配置し、「コントローラー」にロードするライブラリーを指定できます。
// layout.jade
!!!
html
head
title= title || 'Title not set.'
-each script in scripts
script(type='text/javascript', src= script)
body
#header
h1 Header.
#content!= body //- this renders the body of an individual view
#footer
p Footer.
そしてあなたの「コントローラー」:
// app.js
app.get('/', function (req, res) {
res.render({
scripts: ['jquery.min.js', '/nowjs/now.js']
}
}
最新のJade(0.28.1)では、他の場所でページコンテンツ(スクリプトリンク)をハッキングすることなく、テンプレート/ビュー内にすべてを保持することで、正しい方法(tm)を実行できます。
doctype 5 html head //名前付きブロックにより、各ページにカスタムヘッドエントリを追加できます ブロックヘッド title = title link(rel = 'stylesheet'、href = '/ css/style.css') script(type = "text/javascript"、src = "/ js/some- default-script.js ") body block content
extends layout //ここでは、テンプレートヘッドを参照して追加します block append head meta(name = "something"、 content = "blah") link(href = "/ css/another.css"、rel = "stylesheet"、type = "text/css") style div .foo { position:absolute; } script(src = "/ js/page-specific-script.js") ブロックコンテンツ #page-contents-follows
これを行う別の方法を次に示します(ShadowCloudの回答を使用)。少し一般化することで、ローカルスクリプトとリモートスクリプトの両方を指定し、ページの読み込みが完了するまで延期できます。
app.js:
app.dynamicHelpers({
scripts: function() {
//scripts to load on every page
return ['js/jquery.min.js','js/jquery-ui.min.js','js/all.js'];
}
});
次に、ビュー内の任意の場所にローカルスクリプトまたはリモートスクリプトを追加できます。
//- local script
- scripts.Push('js/myPage.js');
//- remote script ( note: this is a schemeless url. You can use http(s)? ones too )
- scripts.Push('//platform.Twitter.com/widgets.js')
layout.jade:(目に見えるものを最初にロードするためにボディの最後に配置しますが、実際にはどこにでも移動できます)
//- Bring the scripts into a client-side array,
//- and attach them to the DOM one by one on page load
script
var page_scripts = !{'["' + scripts.join('","') + '"]'};
function loadJS() {
for(var i in page_scripts) {
var e = document.createElement("script");
e.src = page_scripts[i];
document.body.appendChild(e);
}
}
// Check for browser support of event handling capability
if (window.addEventListener)
window.addEventListener("load", loadJS, false);
else if (window.attachEvent)
window.attachEvent("onload", loadJS);
else window.onload = loadJS;
(これを簡単に読んでから)問題は、配列を「フラッシュ」せずに.lengthを0に設定して古い値を削除することではないため、各リクエストがますます多くの文字列をプッシュする可能性があると思います
これまでの取り組みのポイントは何なのかわかりません。私にとっては、次のことを行う方がはるかにきれいです...
layout.jade:
doctype html
html
head
title= title
block headscripts // placeholder for scripts that need to be in the <head>
link(rel='stylesheet', href='/styles/style.css')
block styles // placeholder for styles
body
block content
script(src='/libs/jquery/dist/jquery.min.js') // this will render before all scripts in every page
block scripts // placeholder for scripts that go in the body
somepage.jade:
extends layout
block styles // this will render in the <head>
link(rel='stylesheet', href='/styles/films.css')
link(rel='stylesheet', href='/styles/pagination.css')
block headscripts // this will also render in the <head>
script(src='/js/somescript.js')
block content
h1= title
div.someotherstuff
block scripts // this will render at the end of the body
script(src='/js/libs/someotherscript.js')
scirpt(src='/libs/doT/doT.js')
このように、.jade
ページのどこにブロックを配置しても問題ありません。常に正しい場所にレンダリングされます。