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

Logging SQL queries in Orchard

It is often useful to see what database queries were made during a specific request in Orchard. There are quite a few ways to do this (you can trace right from SQL Server, or you can use Mini-Profiler for instance), but this morning Sébastien showed me a really easy one that I thought I’d share.

Find the log4net.config file in /src/Orchard.Web/Config and edit it to add the following tag:

<logger name="NHibernate.SQL">
  <priority value="DEBUG" />
</logger>

Restart the application, then hit the URL you want to test, and look at your logs in App_data/logs. You should see new entries looking like this:

2013-04-03 18:57:30,367 [17] NHibernate.SQL -
  SELECT warmupsett0_.Id as Id575_0_,
         warmupsett0_.Urls as Urls575_0_,
         warmupsett0_.Scheduled as Scheduled575_0_,
         warmupsett0_.Delay as Delay575_0_,
         warmupsett0_.OnPublish as OnPublish575_0_
  FROM VuLu_Orchard_Warmup_WarmupSettingsPartRecord warmupsett0_
  WHERE warmupsett0_.Id=@p0;

  @p0 = 1 [Type: Int32 (0)]

(only not as nicely formatted)

To disable the SQL trace, just edit log4net.config and set the value to ERROR instead of DEBUG.

This is how we should read hexadecimal…

Today my five-year-old told me that when she was four, she thought that what came after ninety-nine was… tenty. You know, because seventy, eighty, ninety, tenty.

At first I thought it was just funny and charming, but then I realized it was actually a really good idea. Tenty is only nonsensical if you’re counting in base ten (or lower), but it makes total sense for higher bases.

How do people usually read 0xA0? “A-zero”? How unimaginative! Let’s read that “tenty” from now on!

Here are some more examples of how to read hexadecimal in a non-boring way:

  • 0xB3 is eleventy-three
  • 0xCA is twelvety-ten
  • 0xD9 is thirteenty-nine
  • 0xEC is fourteenty-twelve
  • 0xFF is fifteenty-fifteen
  • 0xF04A is fifteen hexathousand forty-ten
  • 0x4B2AC0AA is forty-eleven hexamillion, two hexahundred tenty-twelve hexathousand tenty-ten
  • and of course, seven-eleven will have to change their logo to 0x7B.

Repeat after me... One, two, three, four, five, six, seven, eight, nine, ten, eleven, twelve, thirteen, fourteen, fifteen, onety, onety-one, and so on.

Is this the greatest thing or what?

Taking an Orchard site offline while you update it

(c) Bertrand Le Roy 2012If your hosted environment does not give you a staging site and the means to swap it easily with the production environment like Azure Cloud Services do, or if you don’t have a staging database, or if you just need to take your site offline for the public while you perform data updates in the admin, you may be wondering what solutions you have, if any.

IIS has an app_offline.htm feature that you can use, that will serve a static page for all requests but that’s rather brutal as it does not just take the site offline for your users, it also does so for you. While that file exists, you can do absolutely nothing with your site. You cannot access the admin, you cannot preview your changes, nothing. So when you flip the switch back, it’s anyone’s guess whether the changes you blindly made actually work, even if they did on your machine…

We need a better solution. Well, I happen to have one...

All you have to do is create a new theme named “Offline” with just one /Views/Layout.cshtml file containing a message along the lines of “We are updating the site. We apologize for the inconvenience. Please come back in a few minutes.” You can add stylesheets to make it pretty if you want to. It’s a full theme, you can go crazy.

The important thing is that this theme has one layout, and that this layout does nothing but display its message. It has no zones, so no dynamic content is going to be served to the public from the site no matter what URL is hit.

Once you have made this theme current, all your visitors are seeing it, but you can still access the admin of the site and do whatever you want.

Better, you can use the “Theme Preview” feature of Orchard to check what your changes look like while your users continue to see the “offline” page. Just go to Themes, and click Preview on your regular theme…

Once you are satisfied with your changes and judge the site to be ready to be taken back online, just restore your theme as the current. The “Offline” theme can sit there and do nothing until the next time you need it.

I’ve used this technique successfully last time I updated an Orchard site. It worked great. I hope it helps others…

Dead simple stubbing for JavaScript

I’m writing a lot of JavaScript these days, and for testing I mostly use QUnit. When I need to quickly stub a piece of the code that I’m testing, I like to use the following micro-library. What it does is enable you to replace a bunch of methods on an object with stub versions, in a easily reversible way.

I use RequireJS, but if you don’t, just remove the define and outer function.

define(function() {
    var stub = function(obj, stubs) {
        obj._stubbed = obj._stubbed || {};
        for (var name in stubs) {
            obj._stubbed[name] = obj[name];
            obj[name] = stubs[name];
        }
    };
    stub.restore = function(obj) {
        if (!obj || !obj._stubbed) return;
        for (var name in obj._stubbed) {
            obj[name] = obj._stubbed[name];
        }
        delete obj._stubbed;
    };
    return stub;
});

Here is how you would replace two methods bar and baz on an object foo:

stub(foo, {
    bar: function() {
        return "stubbed bar";
    },
    baz: function(glop) {
        return "stubbed baz " + glop;
    }
});

And here is how you can put everything back in place once you’re done:

stub.restore(foo);

I hope this helps...

Always have a host or URL prefix on the default Orchard tenant

The multi-tenancy feature in Orchard enables you to host multiple sites within the same Orchard instance. It’s not a a security feature, just a way to improve site density, and to enable you to save on hosting costs. Nevertheless, a request to a specific existing tenant should never be answered with a page from another tenant. Ever.

There is however a fallback mechanism that enables one tenant to handle all requests that weren’t identified by another tenant. While this could be considered useful in some scenarios, I’m hereby declaring it bad practice.

If for any reason a tenant fails to start, for example, requests to that tenant are going to fall back. Even if you were in a scenario where you considered fallback to be useful, this is an unexpected and positively undesirable result. It’s much better to fail with an error message or a 404 than to fail with a fallback to a different site than the one the client asked for.

So here is my recommendation:

Always have a host or URL prefix configured on all tenants, in particular the default tenant.

This way, no fallback will ever happen, and requests will only be handled by a tenant that recognizes its own host name.

Here is, for example, the new configuration of the default tenant on my hosted web sites:

Always specify the host name on your Orchard tenants

Note that I have multiple hosts configured here, including the host that I use on my dev machine for local development, but the point here is to specify something on all tenants.

This is important.

Easy content templates for Orchard, take 2

Placement.info is an XML file that orchestrates the different parts of a content item and sends each of the shapes they create into specific local content zones. If the previous sentence sounded confusing to you, fear not, this post is for you.

When writing an Orchard theme, more often than not, you know exactly what parts exist in your content type, and you know where you want them to render. Placement can be extremely powerful, but it’s rather abstract and it reverses the usual logic of placing contents on a page. What most people really want to do is write a template with simple markup and placeholders inside that markup for the rendering of specific parts such as title, summary, tags, etc. Placement forces you to dispatch those part shapes from a completely separate file.

In the Summer of 2011, I wrote a little article to explain how to write custom templates for specific content types in Orchard, without using placement.info:

So you don’t want to use placement.info?

The solution worked, but relied on a hack that will break with the next version of Orchard (1.7).

Sébastien Ros gave me a little trick the other day that enables the same thing, in a simpler, less hacky form. It still uses placement somewhat, but in a very simple way.

The idea is to create one local zone per part instead of the usual header, content and footer zones. Here we are going to send the relevant shapes to those zones through placement:

<Match ContentType="BlogPost">
  <Match DisplayType="Summary">
    <Place Parts_Common_Body_Summary="Summary:0"
           Parts_Tags_ShowTags="Tags:0"
           Parts_Common_Metadata_Summary="MetadataSummary:0"
           Parts_Comments_Count="CommentsCount:0" />
  </Match>
</Match>

This sends shapes into Summary, Tags, MetadataSummary and CommentsCount zones. Those do not yet exist.

Caveat: when naming your custom zones, be careful not to collide with existing properties or zones on the Model, lest you end up with unexpected and confusing results. Using longish and very explicit names usually works well for that.

The template can now simply create and render those zones. Here is my Content-BlogPost.Summary.cshtml template:

@using Orchard.ContentManagement
@{
    var blogPost = Model.ContentItem;
}
<article class="content-item blog-post">
    <header><h1><a href="@Url.ItemDisplayUrl((IContent)blogPost)">
@blogPost.TitlePart.Title
</a></h1></header> @Display(Model.Summary) <footer> @Display(Model.Tags) @Display(Model.MetadataSummary) @Display(Model.CommentsCount) </footer> </article>

Notice how in the case of the title, I’m not even using the shape given by the part, but I’m accessing the properties directly on the TitlePart. The other parts are rendered through the special zone that we created using the Display function. And that is all. You can now focus on building your template, and it will be pretty obvious what will render where…

Creating simple custom Orchard widgets

If you want to create a simple widget in Orchard, such as a box of social links, you have three possibilities:

  1. Find a module on the gallery or write one yourself, but there is overhead associated with modules, which may make this overkill.
  2. Use an HTML widget and paste a bunch of HTML and Javascript, hoping administrators of the site don’t break it accidentally. I don’t like this, it feels like a hack.
  3. Create a simple widget, following the instructions in this post.

First, let’s create a content type (in the admin, go to Content / Content Types and click “Create new type”) and call it “Social Links”.

Add the widget and identity parts. Those are the only ones you really need:

Pick the identity and widget parts

Uncheck creatable and draftable, add the “Widget” stereotype (with an upper-case ‘W’: I made the mistake, as you can see, of using a lower-case ‘w’ on my first try, and it did prevent the widget from being seen as such):

configuring the new type

Now when you add a widget, the social links widget appears in the list:

The new widget can now be added to a zone

It’s a simple, apparently featureless widget, which minimizes the chances of accidentally messing it up.

All that’s left to do now is to add a template to the theme that will render what we want. We’ll take advantage of shape alternates. Using shape tracing, we quickly discover that we can name our template Widget-SocialLinks.cshtml to target it narrowly enough:

Shape tracing can show us how to override the rendering

Once the file has been added to the Views folder of my theme, I can paste in the code from Facebook, Twitter, or whatever else I want in there.

All done

Done. Fastest and simplest way to create a new widget.

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

Final laptop, ultimate laptop or neither?

Samsung Series 9Jeff Atwood has an interesting post today where he says his current laptop may be the last one he buys. The argument is that tablets are a better option now, with longer battery life, less lap overheating, and a nicer form factor. But well, tablets are not for me. I always need a keyboard, a full version of Windows, I rarely need to run on the battery for very long, and the tablet form factor just doesn’t work for me. I like my screen to stand on its own, even on my lap, and having a separated keyboard is just clumsy. The surface looks like an interesting compromise, but the lack of a robust hinge makes it a no-go for me. Also, I want a single machine that works for everything I do.

I usually buy my desktop machines with a very different approach from the Atwoods and Hanselmans of the world: they seem to always go for the best and change them often, whereas I go for older, cheaper parts that I swap out to make the computers last as long as possible. Buying lots of new devices all the time feels icky to the environmentalist in me.

The last machine I retired was twenty years old and the only reason I changed it was that I got a case for free with the replacement parts I needed. Granted, the case was the only remaining original part. But still, I’ve made it last by swapping old parts with new ones as needed, and it’s been a very economical solution. I never go for the top-of-the-line, makes-your-eyes-bleed-with-ecstasy graphics cards, processors and memory. Instead, I buy year-old-ish parts, in that sweet spot where they have gotten extremely inexpensive but are still the equivalent of last year’s best. Last year was awesome last year, remember? And before you ask, I do most of my gaming on Xbox, so I really don’t need a gaming type of PC.

Laptops are different however: you can’t swap parts so easily. A couple of years ago, I started using my laptop as my main machine. This has the advantage that I can work anywhere with the same tools and data, even if I’m not connected. In my home office, in my rocker in front of the TV, in a coffee house or on the plane. Nothing to copy onto it before I leave, it’s all already there, always, like a little cloud that follows me everywhere I go. Laptops are awesomely light and small nowadays, and they can still pack all the power that I need. When I started working freelance last year, I shopped around and after considering a MacBook Air, I settled on a Samsung Series 9 with 6GB of RAM and 256GB of SSD. I did not want to have to change anything on the machine, and the Samsung was the only machine that reached out of the box all my requirements, one of which was to be very small, and another that I could hook it to a large external screen.

A year after, I still love that machine. I’ve had an issue with the quality of the plastics, and had to replace the piece that surrounds the keyboard after it cracked (covered under the awesome 3-year warranty), and I do resent the lack of anything else than HDMI when I talk at conferences, but overall it’s a fantastic piece of technology and a near-perfect fit for me.

Would I surrender the advantages of having everything I need in a form factor that I like for a hipper tablet? Of course not. As I said, tablets are not for me. They may be fantastic devices, but I need my Visual Studio, my keyboard and my hinge.

Is it the ultimate laptop? Of course not. I wouldn’t mind a retina-like screen, double the SSD, and a little more battery juice.

So why am I telling you all that? In today’s hardware market, we have more variety and form factors than we ever had before: phones, tablets, hybrids, laptops, ridiculously small and cheap microcontrollers that can output HD video, and of course desktops. That’s choice, people, and if you can handle it, it’s a wonderful thing to have. Pick what fits your life and work styles (and make it last).

More Posts « Previous page - Next page »