Spencer Carnage
Spencer Carnage

Reputation: 2066

Use a variable in a Jade include

I'm working with Jade and Express and I would like to use a variable in my include statement. For example:

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

When I do this I get the error EBADF, Bad file descriptor 'templates.jade'

I even tried

include #{templates}

to no avail.

Upvotes: 52

Views: 36382

Answers (5)

danefondo
danefondo

Reputation: 555

It's 2019 and using variables in Pug (previously Jade) mixins has become simple.

When creating your mixin, you can give it parameters as per value(s) you're expecting to pass to the mixin. You can access any nested values using dot notation.

mixinFile.pug:

mixin myMixin(parameter1, parameter2, parameter3)
    h2.MyHeading #{parameter1}
    p.MyParagraph #{parameter2.myVariable}
    .MyBox(id= parameter3.id)

index.pug:

include mixinFile
block content
    +MyMixin(variable1, variable2, variable3)

You can read more in the official Pug documentation on Mixins.

Upvotes: 0

antpaw
antpaw

Reputation: 15985

this also works:

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


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

This probably will not increase the performance that you would expect from using the 'view cache' setting (it's on by default in NODE_ENV === 'production'). Or even break the app (e.g. if files are not available on the hard drive while deploying new code). Also trying to use this trick in a client-side or isomorphic app will not work because the template can not be compiled.

Upvotes: 20

user2956171
user2956171

Reputation: 11

Why do not use jade inheritance?

Render what you want at middleware level:

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

Write common common.jade:

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

Then write file that extends common.jade:

extends common.jade
block sublevel
  h2 Some things are here

Upvotes: 1

Frijol
Frijol

Reputation: 141

Found this page googling for the same question, but in a different context, so thought I'd put my solution (read: workaround) here for posterity:

I wanted to surround my include with more context pulled from the variable, e.g. (simplified):

- 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

Since that doesn't work (Jade doesn't support dynamic includes, as noted by freakish), I hybridized with a mixin:

(Edit– a little more elegant than my previous workaround:)

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

My previous answer:

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/

...

It's not elegant, and it won't work if you need to include more than a few things this way, but at least part of the Jade is dynamic.

Upvotes: 7

freakish
freakish

Reputation: 56467

AFAIK JADE does not support dynamic including. What I suggest is to "include" outside the template, i.e.

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 }

Upvotes: 43

Related Questions