Skip to content


Better support for data-bound server-rendered views and/or templates #289

drauschenbach opened this Issue · 6 comments

3 participants


Client template support in SS is outstanding. But now I'd like to take it to the next level, and bake some data into the view on the server, before it's compiled. I can't find any documentation on this. Is Express required? I'd want to bind values to my main view, or maybe any template, using the ${varName} Jade syntax, since my main app view is a Jade template. Things that would be read out of the package.json file via the read-package-json module, like app name and version, come to mind. Maybe even a session key.

In a client definition, it might be nice to define values alongside the view, so that they can be passed into the Jade compiler:

ss.client.define 'main',
    name: 'index.jade',
      appName: 'myapp'
      appVers: 'myappvers'
    css: ...

And as for rendering parts of Jade templates on the server during compilation, ss-clientjade, as an example, has a process() function that doesn't support passing my own options into the Jade compiler.

I believe the ss.client.templateEngine.use function would also need to be extended:

serverOptions =
  appName: 'myapp'
  appVersion: 'myappvers'
ss.client.templateEngine.use 'ember', serverOptions

Or maybe there is a way to do all this today already?


Hi there

So my general feeling towards this is that I don't want to complicate the SocketStream code with server-side template support at all. There just isn't a need for it.

If you want to show the app's version, just get that data over a standard RPC request and display it on the screen. The only reason to support server-side template rendering is for search engines, but I've already decided not to prioritise SEO as 99% of all SocketStream apps require a user to login to do anything useful.

Of course you can always use Express to render server-side templates, which can be useful for parts of your app which really need SEO support (like an About page or such like).




My challenge right now is that I have to make an RPC call to get the server-side session info, to populate my "current user" object. And because of that, each and every template of mine has this timing issue, where it has a "current user not known yet" state (which is different than "unauthenticated"). And so I am accumulating clutter in my templates and code to deal with this.

Maybe there is a more obvious way. Unlike most example apps I see, my Ember router allows for my pages to be viewed by a guest user, and just certain parts of the page are hidden, and a sign-up dialog shows in the foreground. So the problem is my router routes and outlet setting all happens around 20ms before any RPC call that is launched after a ss.server.on(ready). So it makes it impossible to set up data models to populate controllers in an Ember router's route-on-enter.

Maybe SocketStream apps need to have an Ember router redirect to a "fetching session" state, and then redirect back to where the URL entry point was heading (a deep bookmark). That will flicker, and I will not like it.

SocketStream member


Thanks for describing the issue in more detail. In the case of Dashku, I had a similar case of needing to fetch the current user via an RPC call, but what I chose to do is do almost all of the view rendering via Hogan.js, and have the app.jade be a simple html container with little pre-defined markup.

In terms of rendering multiple client-side templates, I built a simple library to handle doing this, called StateManager. It's got the same principle that Backbone has in that it applies a light structure to switching between states.

If it helps I can put the file in a gist and write a simple example to show how it works. It may be of help.


Ember is being pushed as the framework of choice for SocketStream. And after some headaches with it, I tried Angular, Knockout, and Batman. But those all had even bigger problems with SS, so I'm sticking with Ember. But it remains to be seen how authentication and the Ember router can be integrated, especially when using a deep bookmark as an entry point into the app.

Each of the other frameworks will have their own integration challenges as well, but I think there's better odds of success if we all rally around a single reference point, and for SS, Ember is it.

I love Batman. It leaves you with truly beautiful code and templates. And its data bindings are Jade-friendly, and not handlebars-ugly. I think it's deep durable property paths are the state-of-the-art, and the solution to hacks like Ember Data and how it wants to flatten deep documents (because listening to deep property graphs is too hard the Ember way, the authors say). But, it seems to have a flawed event model and state engine at the moment, and half of the time the data changes didn't propagate to all the dependent properties for me, leaving me with pages that acted like they were driven by a random number generator. I'm sure they'll fix it in the long run, but I can't wait this time around.

I think those other framework's main problems are in two areas: (1) they don't expect you to swap the transport, which you will certainly be doing if you're SocketStream-based, and (2) they don't necessarily take RequireJS into account, and your code can turn ugly fast given that.


I sort of found a work-around for this: store more state on the server, where the userId is known. So an Ember router on-route-enter could perform an RPC call, return a future like Ember Data does, then populate the future with the RPC result once it arrives. In my mini-mongo style pseudo-Ember-Data, for me that means letting the server always filter on user id, instead of setting that param in the caller. So my mongo queries include some macros for current-user that handlebars evaluates on the server within my query rpc handler. That kind of solves a security gap anyways.

SocketStream member

Marking as closed unless anyone objects.

@paulbjensen paulbjensen closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.