Jang a server-side/client-side view engine for MVC and javascript

 c#  6 Responses »
Feb 072012
 

PM> Install-Package Jang

Jang was born out of a desire to have a single template that works on both server and client side using any view engine necessary.
For instance an ajax site that polls for a new comment and inserts it into the page without a post back you’ll have to maintain two views
one for the server-side generation of the initial page and one for the client-side rendering with an ajax call.

Jang makes it easier to have the best of both worlds. With a single call you can render the same view on the server, while at the same time make a call
on the client and render the same view with new data.

Example

Here is a sample view that generates a list of users from a model.

    //userlist.jazz
    < ul>
        @for(var i in model.Model) {
            @jang.renderView("user", model.Model[i])
        }
    < /ul>
    //user.jazz (this is a child view)
    < li>@model.Model.Name< /li>

Server-side Views

Rendering a view on the server side is almost no different from how you render child views in Razor.

    @Html.RenderTemplate(viewName, Model)

This can be done almost anywhere you currently call child views.

Client-side Views

There are two ways to render a client-side view.

Direct call

    jang.renderView("user", model)

This will return the html of the rendered view which you can then use to insert into the dom.

Making an ajax call with jang.ajax will automatically render the view for you and return the resulting html.

    jang.ajax({
        url: '/home/user',
        success: function (result) {
            $("ul#users").append($(result));
        }
    });

On the server side you need to return a proper response for the view to be rendered. A “JangResult” object has been provided to make this easy.

    public ActionResult User()
    {
        return new JangResult(new User {Name = "this is a new user "});
    }

The JangResult automatically determines the view name based on the action or you can specify a different one yourself.

The goal was to make this seamless and invisible to the consumer.

View Engines

Jang was designed to support additional view engines. Support exists for jsRender, Underscore, Mustache and Jazz. (Jazz is currently still in alpha)

The above sample can be translated:

jsRender

    //userlist.jsrender
	< ul>
		{{#each Model}}
			< li>{{=Name}}< /li>
		{{/each}}
	< /ul>

Underscore

    //userlist.underscore
    < ul>
	<% for(var index = 0; index < Model.length; index++) {%>
		<%= jang.renderView("user", Model[index]) %>
	<%}%>
    < /ul>
    //user.underscore (this is a child view)
    < li><%= Model.Name %>< /li>

Mustache

    //userlist.mustache
	< ul>
		{{#Model}}
			< li>{{Name}}< /li>
		{{/Model}}
	< /ul>

The source for this project is hosted on Github at https://github.com/Buildstarted/Jang please fork it and add support for more view engines :)

I’ll have a future post detailing how it all works.

- Ben Dornis

spacer
spacer
spacer
spacer
spacer
spacer
spacer
spacer
spacer
spacer
 Posted by ben at 11:07 am

Socal Code Camp Post-Mortem

 c#  No Responses »
Jan 302012
 

Code Camp is over. I went to a lot of wonderful sessions. A couple of timing issues hit me with the schedule because there were definitely sessions I wanted to attend at the same time as another session I wanted to attend. c’est la vie.

As ~15 of you know I had my first ever speaking engagement on Sunday about Routing in Asp.net. I want to thank all of your for sticking to it until the bitter end. I’m not as flashy as Scott Hanselman. I don’t have the presence of Scott Guthrie. But I gave it my all and it was fun. I’ll definitely do it again.

I realized after the session started that I needed a lot more practice. Nerves got the better of me and basically my brain shut down and forgot everything. I didn’t reference my notes often enough. Alt-tabbed *way* too often. (one viewer mentioned that my scrolling made her dizzy) All in all it was a mess but one that will be refined with more work and a better understanding of the types of questions you attendees asked. Through your questions I was able to see some deficiencies in my presentation that I hope will be fixed next time.

Some of you asked for code. I will post it as soon as I have time to refine it. In it’s current state it doesn’t make for a good download as it’s a huge jumble. I’ll separate my examples out into clear self-contained projects so that each separate concept can be tested and understood on it’s own without any of the other concepts getting in the way.

Another thanks to every who attended and thanks to Code Camp for making it possible.

Ben Dornis

spacer
spacer
spacer
spacer
spacer
spacer
spacer
spacer
spacer
spacer
 Posted by ben at 7:33 am

Socal Code Camp this weekend!

 c#  No Responses »
Jan 252012
 

Sunday, January 29th 2012 will be my first foray into public speaking. I’ll be speaking at Socal Code Camp at Cal State Fullerton about Routing in Asp.Net.

If you’re attending my session please come back to this post afterward and leave comments. Positive or negative doesn’t matter to me as long as they’re constructive. Anything to help improve my future sessions.

Thanks in advance,
Ben Dornis

spacer
spacer
spacer
spacer
spacer
spacer
spacer
spacer
spacer
spacer
 Posted by ben at 4:43 pm

Introducing SignalR.EventStream

 c#  9 Responses »
Dec 072011
 

SignalR.EventStream

Introducing a new favorite Nuget package: SignalR.EventStream.

PM> Install-Package SignalR.EventStream

This is a live feed of the visitors to this site. Leave this page open and watch the live feed. Previous visitors will show up in a few seconds.

SignalR.EventStream

SignalR.EventStream allows users to monitor events happening on the server, live. A single call can be made on the server and propagated to any number of clients. This library leverages the power of [SignalR](https://nuget.org/packages/SignalR) to make the client interface simple.

Born out of a desire to see when new users signed up on csharptube.com/ without refreshing the user list and my familiarity with Jabbr.

What can it be used for?

Some events you might be interested in viewing live.

  1. User signups
  2. Error notifications
  3. Live user mapping (see above)
  4. User notices such as when badges are awarded
  5. Notice when customer makes a purchase
  6. Update a page when a new comment is added
  7. Update a vote count for rankings
  8. Clearly the list is endless…

That’s all great but what is SignalR?

SignalR is a library developed by David Fowler and Damian Edwards that allows asynchronous connections in ASP.Net that allows you to build real-time multi-user web applications. This basically means that you can execute server-side code directly from a client or execute javascript on the client directly from the server. It uses the best connection your browser can support. WebSockets and LongPolling with support for more coming soon.

spacer

Authorize users to view events

There are two methods for streaming. One is Send(..) which sends an event to the “authorized” general group. The second method is SendTo(..) which sends an Event to a specific group of people.

EventStream.Send

The heart of this is that you should be able to send any data to the client and parse it via json. To enable this I’m using Newtonsoft.Json to convert objects passed into a Json string which is then sent to the client. This allows for a lot of flexibility since the client can now handle anything we want. The event type is determined from the type of object passed in – except for anonymous types. You must pass in a specific event type in order to utilize it. Normal string events are typed as “event”.

public interface IEventStream
{
    void Send(string @event);
    void Send(string type, object @event); //mainly used for anonymous types
    void Send(object @event);

    void SendTo(string group, string @event);
    void SendTo(string group, object @event);
    void SendTo(string group, string type, object @event);
}

I throw an exception on anonymous types without a specified string type. One of the interesting gotcha’s in c# is that there’s no built in way to determine if a type is an anonymous one. Borrowing from another project I helped with, (RazorEngine) I’ve pulled in the IsAnonymousType method.

public static bool IsAnonymousType(Type type)
{
    if (type == null)
        throw new ArgumentNullException("type");

    return (type.IsClass
            && type.IsSealed
            && type.BaseType == typeof(object)
            && type.Name.StartsWith("<>", StringComparison.Ordinal)
            && type.IsDefined(typeof(CompilerGeneratedAttribute), true));
}

This has been a very reliable way of checking whether or not a particular type is an anonymous type.

Usage

To send an event to the “authorized” group you simply make the following call.

IEventStream EventStream = new EventStream();
EventStream.Send("A simple string message");

You can easily handle this in javascript.

(function() {
    var eventStream = new EventStream().connect();
    eventStream.eventReceived = function(type, data) {
        console.log(data);
    });
})();

To send an event to a particular group you simply pass in the group you wish to send it to.

IEventStream EventStream = new EventStream();
EventStream.SendTo("message-group", "A simple string message");

If you just wait on this page all events will be captured and alerted. For more complex data, however.

IEventStream EventStream = new EventStream();
EventStream.Send(new UserSignup {
    Username = "Buildstarted",
    Realname = "Ben Dornis",
    BlogUrl = "buildstarted.com"
});

SignalR.EventStream automatically builds a Json string and passes it to the clients.

(function() {
    var eventStream = new EventStream().connect();
    eventStream.eventReceived = function(type, data) {
        /* Handle this more complex object */
    });
})();

Page specific sends

To make things easier to update pages I’ve added a PageStream() type in the eventStream.js. This uses the current pathname of the url as the group. You can then send events to any client currently viewing that page. This makes it really easy to add new comments or modify the rankings for a page.

(function() {
   var pageStream = new PageStream().connect();
   pageStream.eventReceived = function(type, data) {
       //update the vote count!
   };
});

var path = new UrlHelper(ControllerContext.RequestContext).Action("index");
new EventStream().SendTo(path, "this is a page update");

I’m looking at how to create a path from the current request easier than that and externally to a Controller. (update forthcoming).

You can use any simple javascript templating engine that handles json to automatically build an html object and insert it into the dom.

You can find the source for SignalR.EventStream on Github.

–”[SignalR.EventStream] makes me want to look at SignalR”

-Ben Dornis

spacer
spacer
spacer
spacer
spacer
spacer
spacer
spacer
spacer
spacer
 Posted by ben at 9:57 pm

What are your favorite Nuget MVC packages

 c#, MVC, nuget  7 Responses »
Dec 052011
 

What are your favorite MVC packages available on Nuget? Why?

Here are the most common ones I end up installing in a new MVC Application:

  • Elmah – Great for capturing errors (I usually install Elmah for Glimpse as well)
  • Glimpse – Great for monitoring routes and tracing information.
  • RazorGenerator – Precompiled views, compile time checking
gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.