Giter Site home page Giter Site logo

koa-views's Introduction

koa-views

koa-views NPM version NPM downloads Dependency Status License

Template rendering middleware for koa@2.

Installation

npm install koa-views

Templating engines

koa-views is using consolidate under the hood.

List of supported engines

NOTE: you must still install the engines you wish to use, add them to your package.json dependencies.

Example

var views = require('koa-views');

const render = views(__dirname + '/views', {
  map: {
    html: 'underscore'
  }
})

// Must be used before any router is used
app.use(render)
// OR Expand by app.context
// No order restrictions
// app.context.render = render()

app.use(async function (ctx) {
  ctx.state = {
    session: this.session,
    title: 'app'
  };

  await ctx.render('user', {
    user: 'John'
  });
});

For more examples you can take a look at the tests.

Simple middleware

If you need to simply render pages with locals, you can install koa-views-render:

npm install koa-views-render

Then simply use it on your routes and its arguments will be passed to ctx.render.

var render = require('koa-views-render');

// ...

app.use(render('home', { title : 'Home Page' }));

API

views(root, opts)

  • root: Where your views are located. Must be an absolute path. All rendered views are relative to this path

  • opts (optional)

  • opts.autoRender: Whether to use ctx.body to receive the rendered template string. Defaults to true.

const render = views(__dirname, { autoRender: false, extension: 'pug' });
app.use(render)
// OR
// app.context.render = render()

app.use(async function (ctx) {
  return await ctx.render('user.pug')
})

vs.

const render = views(__dirname, { extension: 'pug' })
app.use(render)
// OR
// app.context.render = render()

app.use(async function (ctx) {
  await ctx.render('user.pug')
})
  • opts.extension: Default extension for your views

Instead of providing the full file extension you can omit it.

app.use(async function (ctx) {
  await ctx.render('user.pug')
})

vs.

const render = views(__dirname, { extension: 'pug' })
app.use(render)
// OR
// app.context.render = render()

app.use(async function (ctx) {
  await ctx.render('user')
})
  • opts.map: Map a file extension to an engine

In this example, each file ending with .html will get rendered using the nunjucks templating engine.

const render = views(__dirname, { map: {html: 'nunjucks' }})
app.use(render)
// OR
// app.context.render = render()
// render `user.html` with nunjucks
app.use(async function (ctx) {
  await ctx.render('user.html')
})
  • opts.engineSource: replace consolidate as default engine source

If you’re not happy with consolidate or want more control over the engines, you can override it with this options. engineSource should be an object that maps an extension to a function that receives a path and options and returns a promise. In this example templates with the foo extension will always return bar.

const render = views(__dirname, { engineSource: {foo: () => Promise.resolve('bar')}})
app.use(render)
// OR
// app.context.render = render()

app.use(async function (ctx) {
  await ctx.render('index.foo')
})
  • opts.options: These options will get passed to the view engine. This is the time to add partials and helpers etc.
const app = new Koa()
  .use(views(__dirname, {
    map: { hbs: 'handlebars' },
    options: {
      helpers: {
        uppercase: (str) => str.toUpperCase()
      },

      partials: {
        subTitle: './my-partial' // requires ./my-partial.hbs
      },
      
      cache: true // cache the template string or not
    }
  }))
  .use(function (ctx) {
    ctx.state = { title: 'my title', author: 'queckezz' }
    return ctx.render('./my-view.hbs')
  })

Debug

Set the DEBUG environment variable to koa-views when starting your server.

$ DEBUG=koa-views

License

MIT

koa-views's People

Contributors

avindra avatar botre avatar cuteboi avatar damianb avatar dependabot[bot] avatar edwardzzz avatar g-rath avatar hcz avatar helloyou2012 avatar i5ting avatar ifraixedes avatar int64ago avatar kmohrf avatar lcxfs1991 avatar marcusoftnet avatar matkl avatar merty avatar naxmefy avatar niftylettuce avatar nimthenerd avatar queckezz avatar rkt2spc avatar ruisiang avatar shadowgate15 avatar stevermeister avatar tangdaohai avatar theverything avatar thomasdezeeuw avatar vendethiel avatar wsmpanda avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

koa-views's Issues

Usage of 5.x with koa@1

Now that koa-views 5.x was released, is it possible to use it with koa@1? Or do we need to rollback to 4.x?

Strange issue with partials in handlebars

I'm using almost the exact code you posted in another issue for partials with handle bars:

const Koa = require('koa')
const views = require('koa-views')
const app = new Koa()

app.use(views(__dirname, {
    map: {hbs: 'handlebars'},
    options: {
        partials: {
            subTitle: './my-partial' // requires ./my-partial.hbs
        }
    }
}))

app.use((ctx) => {
    ctx.state = {title: 'my title', author: 'queckezz'}
    return ctx.render('./my-view.hbs')
})

app.listen(8083, () => {
    console.log('Server listening on port 8083')
})

On first render this works... on second, I get an error:

Error: ENOENT: no such file or directory, open '/home/blitzd/WebstormProjects/untitled/<div>Partial Test</div>.hbs'

Instead of trying to load the partial by the filename configured in the code example, it's actually looking for the file with the name being the actual CONTENT from the partial, but this only happens on subsequent requests and never the first.

My main content:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{{> subTitle }}
</body>
</html>

My partial:

<div>Partial Test</div>

Debug output for first and second load:

  koa-views render `./my-view.hbs` with {"partials":{"subTitle":"./my-partial"},"title":"my title","author":"queckezz"} +0ms
  koa-views render `./my-view.hbs` with {"partials":{"subTitle":"<div>Partial Test</div>"},"title":"my title","author":"queckezz"} +6s

How to use layout with handlebars?

Used koa-generator (koa2 -e --hbs) to generate base code, it generates this:

app.use(views(__dirname + '/views', {
  extension: 'hbs',
  map: { hbs: 'handlebars' }
}));

By default this doesn't render the layout.hbs at all so I changed it to this:

app.use(views(__dirname + '/views', {
  extension: 'hbs',
  map: { hbs: 'handlebars' },
  layout: 'layout'
}))

Adding layoutPath: __dirname + 'views/' doesn't seem to work either.

Any ideas or am I doing something wrong here?

deepmerge and circular references

The usage of deepmerge on render() locals onto app.locals would suggest that passing deep structures to views as locals isn't shunned upon, but some very simple scenarios (like passing in an object holding any circular reference at all (a controller or something?) will result in a RangeError. (max call stack size exceeded).

koa-session, as used in the example in the docs, has a _ctx property containing the koa context object. It seems like it'll be inevitable at some point to have circular references on / to the koa object. Passing this koa context into my view via session: this.session is doing just that as I have added some application-specific properties.

Would the circular reference be considered an anti-pattern or could a shallow merge be more appropriate / less costly?

Error: ENOENT: no such file or directory

I use koa-views render html and ejs.

  1. first url = localhost:3333/test1(will render ejs), It works great.
  2. I change url to /test2 (will render html), It works great.
  3. but when I change url to /test1, It not work……

My code:

var koa = require("koa");
var views = require("koa-views");

var app = new koa();

app.use((ctx, next) => {
  const start = new Date();
  return next().then(() => {
    const ms = new Date() - start;
    console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
  });
});

app.use(views(__dirname + "/views", { extension: "ejs" }));

app.use( (ctx, next) => {
    if("/test2" === ctx.path){
        return ctx.render("test2.html"); //render test2.html
    }
    return next();
});

app.use( (ctx, next) => {
    if("/test1" === ctx.path){
        return ctx.render("test1"); //render test1.ejs
    }
    return next();
});

app.listen(3333);

AssertionError: app.use() requires a generator function

npm install koa-views ,install koa-views version is 5.1.2

use with koa 1.x

assert.js:89
throw new assert.AssertionError({
^
AssertionError: app.use() requires a generator function
at Application.app.use (/Users/liwenwu/projects/yuanshuo_koa/node_modules/koa/lib/application.js:106:5)
at Object. (/Users/liwenwu/projects/yuanshuo_koa/app.js:34:5)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Function.Module.runMain (module.js:441:10)
at startup (node.js:134:18)
at node.js:962:3

when npm install [email protected]

it's ok

internal ERROR

TypeError: undefined is not a function
at Object.views (D:\02_yun_io_Remote\Centralc.nfd8.com5\node_modules\koa-views\index.js:105:12)
at GeneratorFunctionPrototype.next (native)
at Object. (D:\02_yun_io_Remote\Centralc.nfd8.com5\node_modules\koa\node_modules\koa-compose\index
:19)
at GeneratorFunctionPrototype.next (native)
at onFulfilled (D:\02_yun_io_Remote\Centralc.nfd8.com5\node_modules\koa\node_modules\co\index.js:65:19)
at D:\02_yun_io_Remote\Centralc.nfd8.com5\node_modules\koa\node_modules\co\index.js:54:5
at Object.co (D:\02_yun_io_Remote\Centralc.nfd8.com5\node_modules\koa\node_modules\co\index.js:50:10)
at Object.createPromise (D:\02_yun_io_Remote\Centralc.nfd8.com5\node_modules\koa\node_modules\co\index.js:30:
at Server. (D:\02_yun_io_Remote\Centralc.nfd8.com5\node_modules\koa\lib\application.js:136:8)
at Server.emit (events.js:110:17)
at HTTPParser.parserOnIncoming as onIncoming
at HTTPParser.parserOnHeadersComplete (_http_common.js:111:23)
at Socket.socketOnData (_http_server.js:343:22)
at Socket.emit (events.js:107:17)
at readableAddChunk (_stream_readable.js:163:16)
at Socket.Readable.push (_stream_readable.js:126:10)
at TCP.onread (net.js:538:20)

Allow passing a prototype object

Hi !

to start off : I'm sorry this is not (yet) a PR, it's 4 am and I'd rather get your opinion first.

We currently have a middleware like this one in our app, but we're currently attaching the locals a few "special variables". Would you be okay to add another parameter that'd be used as the render's __proto__ (or something like that) ?

PS : I think it's better to cache the views(); call, it doesn't need to be called once per request.

Global locals cause server to crash on second page load.

If you add global locals the server will crash on the second page load. This can be seen on the current underscore example. Here is the console output:

Error: yield a function, promise, generator, array, or object
    at next (/Users/cs/Desktop/koa-render/node_modules/koa/node_modules/co/index.js:107:12)
    at Object.<anonymous> (/Users/cs/Desktop/koa-render/node_modules/koa/node_modules/co/index.js:55:5)
    at next (/Users/cs/Desktop/koa-render/node_modules/koa/node_modules/co/index.js:91:21)
    at Object.<anonymous> (/Users/cs/Desktop/koa-render/node_modules/koa/node_modules/co/index.js:55:5)
    at next (/Users/cs/Desktop/koa-render/node_modules/koa/node_modules/co/index.js:91:21)
    at Object.<anonymous> (/Users/cs/Desktop/koa-render/node_modules/koa/node_modules/co/index.js:55:5)
    at Server.<anonymous> (/Users/cs/Desktop/koa-render/node_modules/koa/lib/application.js:105:8)
    at Server.EventEmitter.emit (events.js:101:17)
    at HTTPParser.parserOnIncoming [as onIncoming] (_http_server.js:505:12)
    at HTTPParser.parserOnHeadersComplete (_http_common.js:111:23)

/Users/cs/Desktop/koa-render/node_modules/co-views/node_modules/co-render/node_modules/consolidate/lib/consolidate.js:143
          if (err) return fn(err);
                          ^
TypeError: string is not a function
    at /Users/cs/Desktop/koa-render/node_modules/co-views/node_modules/co-render/node_modules/consolidate/lib/consolidate.js:143:27
    at /Users/cs/Desktop/koa-render/node_modules/co-views/node_modules/co-render/node_modules/consolidate/lib/consolidate.js:95:21
    at fs.js:195:20
    at Object.oncomplete (fs.js:97:15)

Losing the engine

Testing this out I have this code:

app.use(views('../views'), {
    html: 'underscore'
});

app.use(function *(next) {
    this.body = yield this.render('index', { name: 'koa' });
});

and grapped in the index.html file from the Underscore example. But when I open the page I get this error:

TypeError: undefined is not a function
at Object. (/Users/thomas/CloudStation/Dropbox/www/webBlueprint/node_modules/koa-render/node_modules/co-views/node_modules/co-render/index.js:33:5)
at next (/Users/thomas/CloudStation/Dropbox/www/koala/node_modules/koa/node_modules/co/index.js:74:19)
at Object. (/Users/thomas/CloudStation/Dropbox/www/koala/node_modules/koa/node_modules/co/index.js:91:5)
at next (/Users/thomas/CloudStation/Dropbox/www/koala/node_modules/koa/node_modules/co/index.js:74:19)
at Object. (/Users/thomas/CloudStation/Dropbox/www/koala/node_modules/koa/node_modules/co/index.js:91:5)
at next (/Users/thomas/CloudStation/Dropbox/www/koala/node_modules/koa/node_modules/co/index.js:74:19)
at Object. (/Users/thomas/CloudStation/Dropbox/www/koala/node_modules/koa/node_modules/co/index.js:91:5)
at next (/Users/thomas/CloudStation/Dropbox/www/koala/node_modules/koa/node_modules/co/index.js:74:19)
at Object. (/Users/thomas/CloudStation/Dropbox/www/koala/node_modules/koa/node_modules/co/index.js:91:5)
at next (/Users/thomas/CloudStation/Dropbox/www/koala/node_modules/koa/node_modules/co/index.js:74:19)

I enable Debug and got this:

<-- GET /
co-views views ../views {} +0ms
co-views render ../views/index.html {"name":"koa","engine":"html","cache":false} +0ms
co-render render ../views/index.html with {"name":"koa","engine":"html","cache":false} +0ms
--> GET / 200 2ms -

So somewhere the underscore engine is lost and the example doesn't work? Or am I doing something wrong?

Recursive merge function

function merge (a, b) {
  for (var k in b) {
    try {
      if ( a[k].constructor == Object ) {
        a[k] = merge(a[k], b[k]);
      } else {
        a[k] = b[k];
      }
    } catch(e) {
      a[k] = b[k];
    }
  }
  return a;
}

Supports overwriting this.locals variables in subsequent this.render calls

ignore checking the extension ?

I render the file named "index.jade" , and show the error
Cannot find module 'jade'

jade is named pug now . how to ignore the extension????

Multiple koa-views middlewares

Is it possible to use multiple koa-views middleware objects in one application? Adding it once within app like below works.

app.use(views(__dirname + '/views', { map: {pug: 'pug'}, extension: 'pug' }));

However, when I add another instance of the middleware but pointing to another directory, it cannot find the views from the latter. In this example koa-views doesn't even look in /admin/views directory. It 'encouters' the first koa-views middleware, does not find a matching view in /views, and stops.

app.use(views(__dirname + '/admin/views', {
    map: {pug: 'pug'},
    extension: 'pug'
}));

How do I make koa-views continue searching for files if there are multiple middleware instances and the first one does not find the requested view?

Thanks

AssertionError: app.use() requires a generator function

I am using the koa-views in the exact way as mentioned in the README. But somehow its giving me the following assertion error:

assert.js:85
  throw new assert.AssertionError({
  ^
AssertionError: app.use() requires a generator function
    at Application.app.use ($PROJECT_DIR/koatest/node_modules/koa/lib/application.js:106:5)
    at Object.<anonymous> ($PROJECT_DIR/koatest/koatest/server.js:23:5)
    at Module._compile (module.js:556:32)
    at Object.Module._extensions..js (module.js:565:10)
    at Module.load (module.js:473:32)
    at tryModuleLoad (module.js:432:12)
    at Function.Module._load (module.js:424:3)
    at Module.runMain (module.js:590:10)
    at run (bootstrap_node.js:394:7)
    at startup (bootstrap_node.js:149:9)
    at bootstrap_node.js:509:3

Versions Info:

I have a mvc design. I am furnishing my code below:

server.js

const koa = require('koa');
const app = koa();
const views = require('koa-views'); 

// Must be used before any router is used
app.use(views(__dirname + '/src/client/templates', { extension: 'html' })); 

const indexApi = require('./src/backend/routes/indexRoute');
const chatApi = require('./src/backend/routes/chatRoute');

// Use the routes 
app.use(indexApi.routes());
app.use(indexApi.allowedMethods()); 
app.use(chatApi.routes());
app.use(chatApi.allowedMethods()); 


// start server / start listening
app.listen(8080, () =>{
    console.log('App started at 127:0.0.1:8080');
});

indexRoute.js

const Router = require('koa-router'); 
const indexView = require('../views/indexView');

const api = Router();

api.get('/', indexView.IndexHandler); 

module.exports = api;

chatRoute.js

const Router = require('koa-router'); 
const chatView = require('../views/chatView');

const api = Router();

api.get('/chat', chatView.ChatHandler); 

module.exports = api;

indexView.js

// Handler/Controller to handle route requests to index page
let IndexHandler = function *(next) {
    console.log('Entered IndexHandler'); 
    this.state = {
        session: this.session,
        title: 'koatest index'
    };

    // yield this.render('index');
    this.body = 'Ths is indexHanler';
}

exports.IndexHandler = IndexHandler;

chatView.js

// Handler/Controller to handle route requests to index page
let ChatHandler = function *(next) {
    console.log('Entered ChatHandler'); 
    this.state = {
        session: this.session,
        title: 'koatest chat'
    };

    // yield this.render('chat', {user: 'John'});
    this.body = 'this is ChatHandler';
}

exports.ChatHandler = ChatHandler;

NOTE : If I don't use the koa-views middleware, my server runs absolutely fine with all the router functioning properly.

What am I missing here?

How I render the subtemplate?

If I have three templates: header.html, footer.html and main.html, how I render the three views? I know co-views could, but I don't know how koa-views? thanks~
The below is the co-views example.
co(function *(){
var a = render('user', { user: tobi });
var b = render('user.jade', { user: loki });
var c = render('user.ejs', { user: luna });
var html = yield [a, b, c];
html = html.join('');
console.log(html);
})();

set defaultLayout and partials render questions in koa2 koa-views hbs

1,How to set defautlayout with handlebars
2,my code:

app.use(views(__dirname+"/views", {
    extension: 'hbs',
    map: { hbs: 'handlebars' },
    options: {
        partials: {
            error: './error' 
        }
    }
}));

routes/index.js

var router = require('koa-router')();
router.get('/', async function (ctx, next) {
  ctx.state = {
    title: 'koa2 title'
  };

  await ctx.render('index', {
  });
})
module.exports = router;

views/index.hbs

{{> error }}

<h1>{{title}}</h1>
<p>Welcome to {{title}}</p>

first time render ok,
but, when i refresh the browser.display an error:

  xxx GET / 500 12ms -
{ Error: ENOENT: no such file or directory, open 'C:\study\koa2\koa2-hbs\views\error

<h1>{{message}}<\h1>
<h2>{{error.status}}<\h2>
<pre>{{error.stack}}<\pre>
.hbs'
    at Error (native)
  errno: -4058,
  code: 'ENOENT',
  syscall: 'open',
  path: 'C:\\study\\koa2\\koa2-hbs\\views\\error\n\n<h1>{{message}}<\\h1>\n<h2>{{error.status}}<\\h2>\n<pre>{{error.stack}}<\\pre>\n.hbs' }

@f/defaults

Would you mind telling me what '@f/defaults' is in the package.json?

When I tries to do 'npm install koa-views@latest', it throws error

unregistered users are not allowed to access package @f/defaults : @f/defaults

Path is confusing, advise changing the behavior.

The path in express is documented as,

views The view directory path, defaulting to "process.cwd() + '/views'"

This is a useful default and we should adopt it. Further adding to the confusion is that setting the path to,

views('./views/', 'jade')

Only runs from the current directory. Though the path is relative, it's prefixed with the directory of the script that you're executing, but with the environment of execution.

I think both of these should be switched around. Would you accept a patch that made these modifications?

Keep getting error when trying to use koa-views

I have not used koa much, I have used express a bit so this may be me doing something stupid.

Anyway the error I get is:

TypeError: undefined is not a function
    at Object.<anonymous> (C:\Code\Web\testing\nodetest\client\app.js:23:16)
    at GeneratorFunctionPrototype.next (native)
    at next (C:\Code\Web\testing\nodetest\node_modules\koa\node_modules\co\index.js:83:21)
    at Object.<anonymous> (C:\Code\Web\testing\nodetest\node_modules\koa\node_modules\co\index.js:56:5)
    at next (C:\Code\Web\testing\nodetest\node_modules\koa\node_modules\co\index.js:99:21)
    at Object.<anonymous> (C:\Code\Web\testing\nodetest\node_modules\koa\node_modules\co\index.js:56:5)
    at Server.<anonymous> (C:\Code\Web\testing\nodetest\node_modules\koa\lib\application.js:123:8)
    at Server.EventEmitter.emit (events.js:110:17)
    at HTTPParser.parserOnIncoming [as onIncoming] (_http_server.js:504:12)
    at HTTPParser.parserOnHeadersComplete (_http_common.js:111:23)

The code looks like:

var koa = require('koa');
var router = require('koa-router');
var views = require('koa-views');

var app = koa();
var port = 3001;

app.use(router(app));

var viewsDir = __dirname + "\\views";
app.use(views(viewsDir, {
    default: 'jade'
}));

app.get('/', function *(next) {
    yield this.render('index', {});
});

console.log("Setup on Port" + port)
app.listen(port);

I tried swapping this.render to views.render, also just so you are sure there is a folder called views with a file called index.jade, and jade has been installed. None of the examples showed it needing to be required explicitly.

So am I doing anything crazy?

Also on a side note is Vash supported? as I was hoping to use that (as I do like Razor syntax).

Handlebars helpers not being registered

Seems like the helpers are not being registered in handlebars. Code:

index.js:

app.use(views(viewPath, {
  map: {hbs: 'handlebars'},
  options: {
    helpers: {
      hello: (name) => {
        return "Hello " + name;
      }
    }
  }
}));

index.hbs:

<html>
<head><title>View Test</title></head>
<body>
<div>{{hello "Jerod"}}</div>
</body>
</html>

When accessing the page, it throws Error: Missing helper: "hello"

Regular handlebars templates work fine, I have tested it without helpers.

Won't render if options are passed in

I'm trying to set up a single jade file for both SPA's of my app and want to let it load a certain javascript file for each SPA (i.e. load the shop script on the shop SPA and the dashboard script on the dashboard app). I assumed I could have a script tag like this in the single jade file: script(src=#{js}) and then pass in the correct script like so:

const router = require('koa-router')();

router.get('/', function* (next) {
  yield this.render('index', {
    js: 'javascripts/shop.min.js'
  });
});

module.exports = router;

However, when I try to load the shop route, I get a 500 error code in the console and nothing loaded on the page.

Possible to pass additional engine options?

For example, ECT has the option for root, that allows you to specify the view route. Without this option set, the extend functionality of ECT doesn't work properly (it needs full layout path). Is there a way to pass this down to ECT somehow? Thanks!

Set engine options

Is there a way to set options to the template engine?
I'm using nunjucks and I want to set some options, like I would do with nunjucks.configure.

ctx.render is not a function

// dependencies
import Koa from 'koa';
import jade from 'jade';
import path from 'path';

// middleware dependencies
import Router from 'koa-router';
import views from 'koa-views';
import convert from 'koa-convert';

// init
const app = new Koa();
const router = new Router();

// middlewares
app.use(convert(views(__dirname + '/views', { extension: 'jade' })));
app.use(convert(router.routes())).use(convert(router.allowedMethods()));

// routes
router.get('/', async function (ctx, next) {
  await ctx.render('index');
});

// start app
app.listen(8080);
export default app;

What's wrong with this code? I tried different versions, but always get TypeError...

yield this.render('index') call error Error: write EPIPE

my code:

    app.get('/', function* (next) {
         yield this.render('../index.html')
    });

when my iPhone visite the website, terminal report

    Error: write EPIPE
       at exports._errnoException (util.js:890:11)
       at WriteWrap.afterWrite (net.js:769:14)

Could koa-views return a template engine object to config(or operate) it?

var views = require('koa-views');
app.use(views(__dirname + '/views', {
  map: {
    html: 'swig'
  }
}));

I wana get the template engin object (such as swig), to invoke some method of it, such as swig.setFilter(...),but how could I get the template engine object by the variable views ( var views = require('koa-views'); )?

Cannot pass a root dir other than __dirname

I am using koa-views with ejs. I want to put my ejs templates in the views folder in the root dir of my project. When I do this I get an error message saying
{ [Error: ENOENT: no such file or directory, open '/Users/isik/Dev/atelye/masteringtrolls/questions.ejs'] errno: -2, code: 'ENOENT', syscall: 'open', path: '/Users/isik/Dev/atelye/masteringtrolls/questions.ejs' }

Actually I see the path stated is incorrect since I wrote it to be in views:
app.use(views(__dirname + '/views', { map: { ejs: 'ejs' } }));
Is that a bug?

Middleware always defaults to html even if the path has a different extension.

I have configured koa-views with only the views' path which defaults the middleware to 'html'. But when I use ctx.render('index.ejs') the debugging tries to do this 'index.ejs.html' and gives me an undefined response.
To fix it I include the default option to ejs, which outputs index.ejs.ejs but renders normally.

I'm currently using koa@2, I don't know if this might be part of the problem.

Thanks in advance.

import convert from 'koa-convert';
import {wrap} from 'co';

import views from 'koa-views';

app.use(convert(views(VIEWS_PATH)));

app.use(async (ctx, next) => {
  ctx.render = wrap(ctx.render);
  await next();
});

app.use(async (ctx, next) => {
  await ctx.render('index.ejs', {message: 'Hello world!!!'});
  console.log(ctx.body);
});
"dependencies": {
    "co": "4.6.0",
    "ejs": "2.4.1",
    "koa": "2.0.0-alpha.3",
    "koa-convert": "1.2.0",
    "koa-views": "3.1.0"
  }

Trouble rendering html

Hello,

Jade works fine but when I switch to html I get an error. I even downloaded your example and tried it. I am using node version 0.11.13. I would very much appreciate you pointing out where I am going wrong. It would help me get this site into production. I am including all the possible info below. Thank you very much!

The debug statement from console is:
koa-views render index.html with {"user":"John","session":{"views":11}} +267ms

The error message is:
TypeError: undefined is not a function
at Object. (/home/bobby/Dropbox/http/testviews/node_modules/koa-views/node_modules/co-views/node_modules/co-render/index.js:33:5) at next /home/bobby/Dropbox/http/testviews/node_modules/koa/node_modules/co/index.js:99:21) at Object. (/home/bobby/Dropbox/http/testviews/node_modules/koa/node_modules/co/index.js:56:5) at next (/home/bobby/Dropbox/http/testviews/node_modules/koa/node_modules/co/index.js:99:21) at Object. (/home/bobby/Dropbox/http/testviews/node_modules/koa/node_modules/co/index.js:56:5) at next (/home/bobby/Dropbox/http/testviews/node_modules/koa/node_modules/co/index.js:99:21) at Object. (/home/bobby/Dropbox/http/testviews/node_modules/koa/node_modules/co/index.js:56:5) at Server. (/home/bobby/Dropbox/http/testviews/node_modules/koa/lib/application.js:123:8)
at Server.EventEmitter.emit (events.js:110:17)
at HTTPParser.parserOnIncoming as onIncoming

index.js:

var session = require('koa-session');
var router = require('koa-route');
var views = require('koa-views');
var koa = require('koa');
var app = koa();
/**
 * Session.
 */
app.keys = ['secrets'];
app.use(session());
/**
 * Setup views.
 */
app.use(views(__dirname, {
  default: 'html'
}));
app.use(function* (next) {
  var n = this.session.views || 0;
  this.session.views = ++n;
  this.locals = {
    session: this.session
  };
  yield this.render('index', {
    user: 'John'
  });
});
app.listen(3000);
console.log('app running on port 3000');

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>koa views</title>
    <style>
      body {
        font-family: Helvetica;
        text-align: center;
      }
      h1 {
        padding-top: 300px;
        font-weight: 200;
        color: #333;
        font-size: 6em;
      }
      h2 {
        color: #666;
      }
    </style>
  </head>
  <body>
    <h1>koa ♥</h1>
    <h2>John has viewed this site  times.</h2>
  </body>
</html>

is there a way let koa-views surport a new engine?

for example

i want use velocity, but consolidate.js don't surport, so I fix it like this

app.js

app.use(views('views', {
  root: __dirname + '/views',
  map: {
    vm: 'velocityjs'
  },
  ext: 'vm'
}));

consolidate.js

/**
 * velocityjs support.
 */

exports.velocityjs = fromStringRenderer('velocityjs');

/**
 * Haml string support.
 */

exports.velocityjs.render = function(str, options, fn){
  return promisify(fn, function(fn) {
    var engine = requires.velocityjs || (requires.velocityjs = require('velocityjs'));
    try {
      options.locals = options;
      fn(null, engine.render(str, options).trimLeft());
    } catch (err) {
      fn(err);
    }
  });
};

I get a package "velocityjs": "^0.8.2"

should i do this?

TypeError: engine.compileFile is not a function

I'm using koa2 with koa-views

app.use(convert(views(__dirname + '/app/views', {
    map: {
        html: 'jade'
    }
})))

app.use(async (ctx, next) => {
    ctx.render = co.wrap(ctx.render.bind(ctx))
    await next()
})

I'm getting this error TypeError: engine.compileFile is not a function when browse to the url. Could someone help me figure what went wrong here?

[Custom Engine]: allow to override consolidate

Eventually, engines are not registered on consolidate and if they don't, there is no way to use them with this module. This is the case of for example Angular Universal which has its own Engine and works with Express OOTB without using consolidate like this. It would be good to be able to do the same in Koa.

What is the equivalent to Express's `app.locals`

I'm trying to pass the session to the jade templates so I can check things e.g. authentication, userlevel, so on so forth, but I can't for the life of me figure out how to pass it to locals from a middleware, e.g. in my express 4 app:

app.use((req, res, next) => {
   app.locals.req = req;
   next();
});

now in Koa2

app.use(async (ctx, next) => {
    try {
        console.log(ctx.req.locals);
        console.log(ctx.req.state);
                console.log(ctx.state);
                console.log(ctx);
        ctx.state.session = ctx.session;
        await next();
    } catch(err) {
        ctx.body = { message: err.message };
        ctx.status = err.status || 500;
    };
});

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.