Tales from the Evil Empire

Bertrand Le Roy's blog

News


Bertrand Le Roy

BoudinFatal's Gamercard

Tales from the Evil Empire - Blogged

Blogs I read

My other stuff

Archives

October 2012 - Posts

Writing an unthemed view while still using Orchard shapes and helpers

This quick tip will show how you can write a custom view for a custom controller action in Orchard that does not use the current theme, but that still retains the ability to use shapes, as well as zones, Script and Style helpers.

The controller action, first, needs to opt out of theming:

[Themed(false)]
public ActionResult Index() {}

Then, we still want to use a shape as the view model, because Clay is so awesome:

private readonly dynamic _shapeFactory;

public MyController(IShapeFactory shapeFactory) {
    _shapeFactory = shapeFactory;
}

[Themed(false)]
public ActionResult Index() {
    return View(_shapeFactory.MyShapeName(
        Foo: 42,
        Bar: "baz"
        ));
}

As you can see, we injected a shape factory, and that enables us to build our shape from our action and inject that into the view as the model.

Finally, in the view (that would in Views/MyController/Index.cshtml here), just use helpers as usual. The only gotcha is that you need to use “Layout” in order to declare zones, and that two of those zones, Head and Tail, are mandatory for the top and bottom scripts and stylesheets to be injected properly. Names are important here.

@{
    Style.Include("somestylesheet.css");
    Script.Require("jQuery");
    Script.Include("somescript.js");
    using(Script.Foot()) {
        <script type="text/javascript">
            $(function () {
                // Do stuff
            })
        </script>
    }
}
<!DOCTYPE html>
<html>
    <head>
        <title>My unthemed page</title>
        @Display(Layout.Head)
    </head>
    <body>
        <h1>My unthemed page</h1>
        <div>@Model.Foo is the answer.</div>
    </body>
    @Display(Layout.Tail)
</html>

Note that if you define your own zones using @Display(Layout.SomeZone) in your view, you can perfectly well send additional shapes to them from your controller action, if you injected an instance of IWorkContextAccessor:

_workContextAccessor.GetContext().Layout
    .SomeZone.Add(_shapeFactory.SomeOtherShape());

Of course, you’ll need to write a SomeOtherShape.cshtml template for that shape but I think this is pretty neat.

TypeScript first impressions

Anders published a video of his new project today, which aims at creating a superset of JavaScript, that compiles down to regular current JavaScript. Anders is a tremendously clever guy, and it always shows in his work. There is much to like in the enterprise (good code completion, refactoring and adoption of the module pattern instead of namespaces to name three), but a few things made me rise an eyebrow.

First, there is no mention of CoffeeScript or Dart, but he does talk briefly about Script# and GWT. This is probably because the target audience seems to be the same as the audience for the latter two, i.e. developers who are more comfortable with statically-typed languages such as C# and Java than dynamic languages such as JavaScript. I don’t think he’s aiming at JavaScript developers. Classes and interfaces, although well executed, are not especially appealing.

Second, as any code generation tool (and this is true of CoffeeScript as well), you’d better like the generated code. I didn’t, unfortunately. The code that I saw is not the code I would have written. What’s more, I didn’t always find the TypeScript code especially more expressive than what it gets compiled to.

I also have a few questions.

Is it possible to duck-type interfaces? For example, if I have an IPoint2D interface with x and y coordinates, can I pass any object that has x and y into a function that expects IPoint2D or do I need to necessarily create a class that implements that interface, and new up an instance that explicitly declares its contract? The appeal of dynamic languages is the ability to make objects as you go. This needs to be kept intact.

UPDATE: this works.

More technical: why are generated variables and functions prefixed with _ rather than the $ that the EcmaScript spec recommends for machine-generated variables?

In conclusion, while this is a good contribution to the set of ideas around JavaScript evolution, I don’t expect a lot of adoption outside of the devoted Microsoft developers, but maybe some influence on the language itself. But I’m often wrong. I would certainly not use it because I disagree with the central motivation for doing this: Anders explicitly says he built this because “writing application-scale JavaScript is hard”. I would restate that “writing application-scale JavaScript is hard for people who are used to statically-typed languages”. The community has built a set of good practices over the last few years that do scale quite well, and many people are successfully developing and maintaining impressive applications directly in JavaScript.

You can play with TypeScript here: http://www.typescriptlang.org

More Posts