2

I want to use marko template engine along with expressjs 4.0 When I remove the default express template engine I am getting following error

Error: No default engine was specified and no extension was provided. at new View (E:\nodeleap\node_modules\express\lib\view.js:48:42) at EventEmitter.app.render (E:\nodeleap\node_modules\express\lib\application.js:545:12) at ServerResponse.res.render (E:\nodeleap\node_modules\express\lib\response.js:938:7) at E:\nodeleap\config\express.js:106:19 at Layer.handle [as handle_request] (E:\nodeleap\node_modules\express\lib\router\layer.js:82:5) at trim_prefix (E:\nodeleap\node_modules\express\lib\router\index.js:302:13) at E:\nodeleap\node_modules\express\lib\router\index.js:270:7 at Function.proto.process_params (E:\nodeleap\node_modules\express\lib\router\index.js:321:12) at next (E:\nodeleap\node_modules\express\lib\router\index.js:261:10) at Layer.handle [as handle_request] (E:\nodeleap\node_modules\express\lib\router\layer.js:78:12)

Jack
  • 9,151
  • 2
  • 32
  • 44
Dinoop mathew
  • 248
  • 1
  • 4
  • 18
  • 2
    The project's README [mentions this in the FAQ](https://github.com/raptorjs/marko#faq) -- "*How can Marko be used with Express?*" "*The recommended way to use Marko with Express is to bypass the Express view engine and instead have Marko render directly to the response stream [...]*" – Jonathan Lonowski Apr 19 '15 at 16:15

2 Answers2

3

It looks like marko is not yet supported by express view engines (see here: https://github.com/tj/consolidate.js)

Edit: But the Marko FAQ recommends not using the express view engine. Option 1 below should work.

So I see a few options, 1. Simply render your templates using marko directly in each of your routes or 2. Set up your own express view engine, and maybe even 3. Make a PR to consolidate.js to add marko support so that others can enjoy :)

Options 1 and 2 would look something like this:

var express = require('express');
var app = express();
var fs = require('fs');
var marko = require('marko');

// Option 2
app.engine('marko', function(filePath, options, callback) {
    marko.load(filePath).render(options, function(err, output) {
        callback(null, output);
    });
});

app.set('views', './views');
app.set('view engine', 'marko');

app.get('/viewengine', function(req, res) {
    res.render('hello', {
        name: 'Frank'
    });
});

// Option 1
var template = marko.load(require.resolve('./views/hello.marko'));
app.get('/marko', function(req, res) {
    template.stream({
        name: 'Frank'
    })
        .pipe(res);
});

var server = app.listen(3000, function() {
    var host = server.address().address;
    var port = server.address().port;
    console.log('Example app listening at http://%s:%s', host, port);
});
Andrew Lavers
  • 8,023
  • 1
  • 33
  • 50
  • Hmm, it seems I did not RTFM, you should definitely follow Jonathan's advice (option 1) – Andrew Lavers Apr 19 '15 at 16:49
  • 1
    Notes on option 2 -- The `callback` can be passed to `.render()` in place of the `function(err, output)`, allowing Express to be aware of any `err`s that occur. You may also want to check `options.cache` and store the `.load`'ed views by their `path`s if that's `true` to avoid always recompiling with each use. – Jonathan Lonowski Apr 19 '15 at 16:58
0

Update :

when i'm answering you is 2019-9-13, and l'm using node v10 LTS, so my answer will be a bit different from last one accordind to docs, but at this time it works fine...

actualy we dont need to set template engine for marko, because they added some modules for us to connect to express. this is the best way which documention suggested.

npm install express --save
npm install marko --save

after that create your app.js file and do as following:

"use strict";

require("marko/node-require"); // Allow Node.js to require and load `.marko` files

let express = require("express");
let path = require("path");
let markoExpress = require("marko/express");
let template = require("./views/index.marko");

let app = express();

app.set("views", path.join(__dirname, "views"));
app.use(markoExpress()); //enable response.marko(template, data)

app.get("/", (request, response) => {
  response.marko(template);
});
app.listen(5000);

after this create your template file i your view directory which in this case is ./views/index.marko and write:

$ const name = "world";
<h1>Hello ${name}!</h1>

it is a simple hello world app with node,express and marko

sina
  • 2,103
  • 1
  • 19
  • 26