2012-08-26 3 views
47

Ich arbeite mit Jade und Express und ich möchte eine Variable in meinem Include-Anweisung verwenden. Zum Beispiel:Verwenden Sie eine Variable in einem Jade Include

app.js

app.get('/admin', function (req, res) { 
    var Admin = require('./routes/admin/app').Admin; 

    res.render(Admin.view, { 
    title: 'Admin', 
    page: 'admin' 
    }); 
}); 

layout.jade

- var templates = page + '/templates/' 

include templates 

Wenn ich dies tun erhalte ich die Fehler EBADF, Bad file descriptor 'templates.jade'

Ich habe sogar versucht

include #{templates} 

umsonst.

+0

ich suchte dies auch . Überrascht wurde diese Funktion noch nicht hinzugefügt. Verzichtete das Repo, um zu sehen, wie schwierig es wäre, diese Funktionalität zu implementieren. –

Antwort

41

AFAIK JADE unterstützt keine dynamische Einbeziehung. Was ich vorschlagen, ist außerhalb der Vorlage zu "schließen", dh

app.js

app.get('/admin', function (req, res) { 
    var Admin = require('./routes/admin/app').Admin; 
    var page = 'admin'; 

    var templates = page + '/templates/'; 

    // render template and store the result in html variable 
    res.render(templates, function(err, html) { 

     res.render(Admin.view, { 
      title: 'Admin', 
      page: page, 
      html: html 
     }); 

    }); 

}); 

layout.jade

|!{ html } 
+0

Das funktioniert auch. Vielen Dank! –

+2

Es scheint, als ob der Aufruf von render() zweimal die Leistung negativ beeinflussen könnte. –

+0

@StephenDavis Ja, aber ich bezweifle, dass es jemals ein Problem sein wird (Datenbank ist immer ein Flaschenhals). – freakish

6

dieser Seite für die gleiche Frage googeln, aber in einem anderen Kontext, so dachte ich, würde ich meine Lösung (lesen Sie hier: Problemumgehung) für die Nachwelt:

wollte ich meinen Einschluss mit mehr Kontext umgeben, der von der Variablen gezogen wurde, z. (Vereinfacht):

- var templates = page + '/templates/' 
- var headid = page + 'head' 
- var imgsrc = '/images/' + page 
div(id=headid)  
    h1 #{page} 
    img(src=imgsrc) 
div(id=page) 
    include templates 

Da das nicht funktioniert (Jade nicht unterstützt dynamische enthält, wie durch freakish bemerkt), I hybridisiert mit einem mixin:

(Bearbeiten- ein wenig eleganter als meine frühere Abhilfe :)

mixin page1 
    include page1/templates 

mixin page2 
    include page2/templates 

... 

- for (var i = 0; i < 3; i++) 
    - var page = 'page' + i 
    - var headid = page + 'head' 
    - var imgsrc = '/images/' + page 
    div(id=headid)  
    h1 #{page} 
    img(src=imgsrc) 
    div(id=page) 
    +page 

meine Antwort:

mixin templates(page) 
    - var headid = page + 'head' 
    - var imgsrc = '/images/' + page 
    div(id=headid)  
    h1 #{page} 
    img(src=imgsrc) 

+templates('page1') 
#page1 
    include page1/templates/ 

+templates('page2') 
#page2 
    include page2/templates/ 

... 

es ist nicht elegant, und es wird nicht w Ork, wenn du mehr als ein paar Dinge auf diese Weise einbeziehen musst, aber zumindest ein Teil des Jade ist dynamisch.

19

funktioniert das auch:

//controller 
var jade = require('jade'); 
res.render('show', {templateRender: jade.renderFile}); 


//template 
!= templateRender('my/path/'+dynamic+'.jade', options) 

Dies wird wahrscheinlich nicht die Leistung erhöhen, die eine Verwendung der 'view cache' Einstellung erwarten würde (es standardmäßig ist los in NODE_ENV === ‚Produktion‘). Oder brechen Sie die App sogar ab (z. B. wenn bei der Bereitstellung von neuem Code keine Dateien auf der Festplatte verfügbar sind). Auch der Versuch, diesen Trick in einer clientseitigen oder isomorphen App zu verwenden, funktioniert nicht, da die Vorlage nicht kompiliert werden kann.

+1

Das ist ziemlich toll –

+1

Aber anstatt die Funktion mit 'Kontext' aufzurufen, sollte es' local's sein. –

+0

http://jade-lang.com/api/ Ein Optionsobjekt, das auch als Locals-Objekt verwendet wird. Es ist beides. – antpaw

1

Warum keine Jade-Vererbung verwenden?

Render, was Sie bei Middleware-Ebene wollen:

res.render('templates/' + template_name + '.jade') 

schreiben gemeinsam common.jade:

h1 This is a page 
.container 
    block sublevel 
    h2 Default content 

Dann Datei schreiben, die common.jade erweitert:

extends common.jade 
block sublevel 
    h2 Some things are here