Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Express rendering methods #6

Closed
c3c opened this issue Sep 11, 2012 · 17 comments
Closed

Adding Express rendering methods #6

c3c opened this issue Sep 11, 2012 · 17 comments

Comments

@c3c
Copy link

c3c commented Sep 11, 2012

First of all, kudos on this project!

Vash is only a "template-maker" at the moment, and can't be used with Express out of the box (that I know of? :P)

https://github.com/elmerbulthuis/jshtml/blob/master/index.js
That file (and in particular, the .render method) makes the lexer of that Razor renderer an actual template engine that is compatible with Express.

I would greatly appreciate the option of being able to integrate Vash with Express :)

@kirbysayshi
Copy link
Owner

Vash used to be compatible with express out of the box, but apparently I've fallen behind with those updates. Especially with express 3, which puts partial and layout support into the specific engines, this will be a little bit of work. More info is available here.

I'm thinking two things:

  1. Add Vash to the consolidate project, which will automatically handle the boring parts, like loading files, caching, etc.
  2. Add express-specific helpers (this is brand new in Vash 0.5x, and I haven't updated the README yet) for things like setting the layout and rendering partials from within a template. This would allow for @html.partial('path/to/the/partial') and @html.layout('path/to/the/layout'), and would still leverage the internals of consolidate.

When using Vash client-side, none of this is an issue. It's easy to just reference the "template store" from within a template, JST['nameofpartialtemplate']().

So, having said that... if you're up to trying to implement this (it's really not that hard, honest!), definitely let me know and give it a shot. Otherwise, I'll add it to my list.

@c3c
Copy link
Author

c3c commented Sep 11, 2012

I was looking into consolidate as well... perhaps that's the easiest, but I was thinking adding renderFile to Vash would be cleanest.
I've registered my github account an hour ago.. It WILL be cruft, but I'm gonna give it a try! :P

@kirbysayshi
Copy link
Owner

Well, renderFile is just something that jshtml cooked up, it's not part of any particular spec. I would recommend consolidate, or even just express support straight up:

vash.__express = function(filepath, options, cb){
    var fs = require('fs');
    fs.readFile(filepath, 'utf8', function(err, contents){
        if( err ){ return cb(err); }    
        var tpl = vash.compile(contents);
        console.log(tpl.toString());
        cb(null, tpl(options)); 
    })
}

Consolidate is basically the same thing.

The difficult part is not getting express to use Vash, it's adding in things like partials, layouts and/or blocks. For that, I'm actually thinking I might need a second project/package called vash-ve, for view engine.

@c3c
Copy link
Author

c3c commented Sep 11, 2012

Yes, I understand now that Vash was in the first place meant to be a lexer more than a view engine. Vash-ve might be more appropriate indeed, sorry.
If you would consider a new project, I have a Very Awesome name proposal: Vagine!
(just kidding though :D)

@kirbysayshi
Copy link
Owner

Ha, yeah no. :)

I just pushed basic express support: https://github.com/kirbysayshi/Vash/blob/2317997e8eb1b577daf2dcbe00926ab60f47cec6/src/vexpress.js. You should be able to just do app.set('view engine', 'vash') and it should work.

@c3c
Copy link
Author

c3c commented Sep 12, 2012

Thanks! Much appreciated. Out of the country for 10 days, so sublimetext will be waiting for me when I get back to continue!

@kirbysayshi
Copy link
Owner

As of right now, the code in master has a much of view engine support: d5c8ef3.

It also supports express a little better. The next stab at this will have to be a big rewrite, because a lot of this stuff should be handled at compile time, and not at runtime (like it is now).

@c3c
Copy link
Author

c3c commented Sep 20, 2012

Hello,

Nice work. Just poked around a bit with vash, but got the following error when trying to hook vash into express:

500 Error: ENOENT, no such file or directory 'C:\codeine\app\views\C:\codeine\app\views\pages\main.html.vash.vash' (please don't judge my windows usage :D)

I think the following code in the vash lib might cause this:

    filepath = filepath.indexOf(options.settings.views) > -1
                ? filepath
                : options.settings.views 
                    + '/' + filepath 
                    + '.' + options.settings['view engine'];

Which renders to this path:
C:\codeine\config\environments/../../app/views/C:\codeine\app\views\pages\main.html.vash.vash

@kirbysayshi
Copy link
Owner

Yep, that makes perfect sense. I assume in your call to res.render you're naming the template + extension? If Vash is set as your view engine, and your views end with .vash as an extension, it should work.

Don't get me wrong, this is definitely a bug, but this is the simple fix you can do while I patch things up.

@kirbysayshi
Copy link
Owner

Could you post your app.configure block, or wherever you're defining which view engine to use and where views should be? And can you also post your res.render call, where you specify the template name?

I thought I had this fixed, but I had misread your report. I missed that in addition to the double extension, you are also getting weird double paths. If you post the above things, it will help me narrow things down.

@c3c
Copy link
Author

c3c commented Sep 20, 2012

I'm using the LocomotiveJS framework, which does the res.render call I think.

  this.set('views', __dirname + '/../../app/views');
  this.set('view engine', 'vash');
  this.engine('vash', vash.__express);

@kirbysayshi
Copy link
Owner

Grab the newest version from NPM, and add this line, if your views end with .html:

this.engine('html', vash.__express);

And then please post the error if any.

@c3c
Copy link
Author

c3c commented Sep 20, 2012

Yeah it tries to load pages\main.html.vash now :) (which is correct)
The line you used didn't work for me, but that's possibly due to LocomotiveJS, which proxies the express functions.

  this.set('view engine', 'vash');
  this.engine('vash', vash.__express);

EDIT: and for a different extension:

this.format('html', { extension: '.vash' });

@kirbysayshi
Copy link
Owner

I've never seen locomotive before. I think part of the problem is the way you're specifying your views folder. I don't think it's necessary, since the locomotive guide for views doesn't have it. You should only need:

this.set('view engine', 'vash')

And if you're using templates that have .html as an extension instead of .vash, then also specify that:

this.engine('html', vash.__express)

@kirbysayshi
Copy link
Owner

So it's working now? My last comment posted at the same time as yours... I'm on bad hotel internet so it took forever.

@c3c
Copy link
Author

c3c commented Sep 20, 2012

It's too soon to tell if everything is working, but this part definitely does work. The razor templating can begin! :D
Enjoy the place you're staying :)

@kirbysayshi
Copy link
Owner

Ok, good to hear. If you encounter any more bugs, open a new ticket!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants