Orchard Media Library and Dropbox

The new Media Library module in Orchard 1.7 has many interesting new features, and I was particularly excited by the ability to import images from Bing via the Web Search feature which was presented at Orchard Harvest this year.

Being a regular Dropbox user, the idea of being able to import media straight from the cloud seemed very useful, so I got to work on a Dropbox media import feature which you can now find over on the Orchard Gallery.

Installation & Getting Started

After installing the module on your Orchard site you will need to create an API Key over on your Dropbox Developer Console. There are a few questions that you have to answer to create the right kind of key, so ensure you create a Dropbox API app, with access to files and datastores, that can access all file types already present on Dropbox. See the screenshot below if you aren’t sure.

Once you receive the App Key and App Secret, head over to your Orchard site and go to Dashboard » Settings » Media to save them.

When you are ready to start importing media, you’ll see Dropbox appear on the media import screen. The first time you do this, you’ll need to link your Orchard user with a Dropbox account. This uses OAuth, so you’ll be briefly redirected to the Dropbox site to confirm that you wish to proceed.

After authenticating with Dropbox, you are ready to start importing media! You can browse all your Dropbox folders, and can preview images Ctrl-clicking will allow multiple selection.

Technical stuff

The source is available over on GitHub. Please direct your pull requests there.

The module uses Dropnet to talk to Dropbox, making use of the Core API features. (Dropnet is itself based on RestSharp, a fantastic library).

The UI was implemented using knockout.js. This was my first foray into client side MVVM, and a very pleasant experience. Needless to say I will be client side MVVM’ing all the things in the future.

The thumbnail images are cached in the browser, although ideally they would be downloaded directly from Dropbox without generating another request to Orchard (see below). If you notice thumbnails not updating, try clearing your browser cache.

To do

There are still one or two things left to do with this module but haven’t got round to just yet, namely:

  • Ability to delete Dropbox credentials from a user in case they want to switch accounts
  • Offer the option to use public links to files, hosting the files on Dropbox instead of importing them into the media library.
  • Download thumbnail images directly rather than through Orchard site

That’s all! I hope you find this module useful, I’ve had a lot of fun writing it.

Questions, comments, suggestions? I sporadically tweet.

Content & Display type alternates for content parts in Orchard

The Shape Tracing feature for Orchard makes it a snap to find and override shapes all over your sites, and I use it regularly to create alternates. A common use case is to find and override a part’s shape based on it’s content type – really useful if you want to alter how a part looks if it is on a page, product, contact, etc. I found myself in a scenario today where I wanted to override a shape based on both the content type or the display type, and both at the same time.

The documentation on Alternates lists only 2 alternates for parts, [ShapeType]__[ContentType], and [ShapeType]__[Id], but thanks to Orchard’s near-infinite level of flexibility, we can quite easily add as many alternates as we want.

A quick read through WidgetAlternatesFactory and UrlAlternatesFactory should be more than enough to get you started, but the key is to latch on to when a shape is displayed, and inject some alternate shape names.

I ended up with the following implementation:

public class PartContentTypeAlternateFactory : ShapeDisplayEvents {
    public override void Displaying(ShapeDisplayingContext context) {
        context.ShapeMetadata.OnDisplaying(displayedContext => {
            var shapeType = displayedContext.ShapeMetadata.Type;
            var contentItem = displayedContext.Shape.ContentItem;
            var displayType = displayedContext.ShapeMetadata.DisplayType;
            var contentType = contentItem.ContentType;
            displayedContext.ShapeMetadata.Alternates.Add(
                String.Format("{0}__{1}", shapeType, displayType));
            displayedContext.ShapeMetadata.Alternates.Add(
                String.Format("{0}__{1}__{2}", shapeType, (string)contentType, displayType));
            });
    }
}

And you end up with some alternates like this:

Surprisingly, I couldn’t find any information about people hitting this problem before (maybe I’m just doing it wrong?), but if this helps let me know in the comments!

Alternates are very powerful, for example you can customise the shape of the first item on your blog, override shapes based on the current URL, and much more.

Happy Orcharding!

Pushover notifications for Orchard CMS

I’m a big fan of Pushover – a push notification service – having used it for a few months for notifications from some home automation tasks. It’s free after purchasing the inexpensive app (for under 5k messages/month), easy to use, and useful for those small but important messages that might normally get swallowed into the great void some of us call ‘Email’.

This fits in quite nicely with Orchard‘s rather useful Rules module, as integration with Pushover would allow us to receive notifications to our mobile devices when events happen on an Orchard site, such as content being created, comments submitted by readers, or events fired from other modules.

So to glue this all together I’ve written a new module for Orchard called Kobowi.Pushover (source), making use of the rules and tokens modules for completely customisable messages triggered from almost any event!

To get started, you’ll need a Pushover account and an API key, and of course either the iOS or Android app installed on your device. Once you have entered the API key under your site settings, you can then start creating rules which use “Send a Pushover message” as an action.

The module uses a very simple wrapper around Pushover’s RESTful API called pushover-dotnet, which you can use to easily add Pushover notifications to your own projects.

I hope that you find this useful, and as always I’m eagerly awaiting any feedback :)

Visual Studio Achievements now in WordPress Plugins Directory

I’ve moved my Visual Studio Achievements plugin for WordPress over to the WordPress Plugins directory, so it is more accessible to users (also gives us auto updates, sweet!)

Unfortunately it seems rather difficult to keep both Git and Subversion copies of the same repository going at the same time, so the repo over on GitHub is now obsolete, but I’ll make sure any tickets raised over there are fixed in the SVN repo.

If you want a demo of the widget, take a look in the sidebar. Check it out and let me know what you think!

NullReferenceException vs ArgumentNullException

I answered a question on StackOverflow today that unfolded into a bit of a debate about the NullReferenceException and ArgumentNullException classes in the .NET Framework.

MSDN states that the NullReferenceException

…is thrown when there is an attempt to dereference a null object reference.

While ArgumentNullException

…is thrown when a null reference (Nothing in Visual Basic) is passed to a method that does not accept it as a valid argument.

Konrad Rudolph (StackOverflow profile) made the point that we don’t need both types as if thrown they both logically mean that you are attempting to use a null reference, so ArgumentException is redundant. While I don’t think the documentation is completely clear (it could do with comparing each to the other to clear up any confusion), I disagree with Konrad’s assertion.

I believe that the NullReferenceException should be thrown when you are attempting to perform a dereferencing operation on a null reference, whereas the ArgumentNullException should be used when you are actively rejecting an argument because it is null. Konrad goes on to say that ultimately, the two operations are the same – i.e. “I’m trying to dereference this null reference therefore I need to throw an NRE” and “I want to dereference this null reference, so I need to throw an ANE as I cannot attempt to do this” – as they all come back to trying to dereference a null reference. However, I think Konrad is missing the difference in semantics between those two operations.

Konrad also suggests that the presence of both types is a bad decision in the design of the framework. Again, I disagree. There are actually 9 classes that inherit from ArgumentException that are there specifically to help us deal with invalid argument, i.e. the likes of ArgumentOutOfRangeException, InvalidEnumArgumentException et al.

Ultimately I expect it all comes down to a matter of taste. Personally I’d rather be told “Whoa, you can’t do that! obj is null man, wtf?” than “Object reference not set to an instance of an object”, which – let’s face it – any seasoned .NET dev has seen enough of to last a lifetime.

What do you think?

Also, thanks to asawyer who was arguing from the same position as myself.

Text Editor embedded in a data: URI.

Well, I saw Snake in a data: URI last week on Hacker News and thought it would be pretty darn awesome to make an editor that would fit in a data: URI.

Everything is stored in the URI after the hash. So, you can open it up, edit some text, hit save, then copy the new URL and use that. I’m pretty sure there is some upper-limit on the size of URIs (IE8 apparently doesn’t like any that are bigger than 32KB), so I’d think twice about pasting your master’s thesis in to it.

Click here for awesome.

You can see the pre-minification version on GitHub.

SkySerial: Read programme information from your Sky+ box

Browsing through an old backup the other day, I stumbled across some code I started writing back in late 2008/early 2009: SkySerial. Most Sky/Sky+ boxes shipped in the UK are made by Pace, and appear to have an RS232 port on the back of them. This is used to output some kind of Nielsen ratings information, has been used as the interface for Sky’s Gnome thingy, and provides data for a third-party control and monitoring program about what you are watching (for feedback from commands issued by the RF2 interface).

SkySerial is a C# implementation of a parser that understands these messages, and includes a small console program so you can see what is on the telly! I’ve since tidied it up a bit, added some unit tests, and tested against the latest firmware on my own Sky box.

Here it is running on my media PC:

The source, as usual, is over on BitBucket. If you find a use for it, let me know :-)

Paging in Orchard

One of my favourite things about Orchard is Shapes, and how we can easily create reusable pieces of functionality that can be placed almost anywhere on your site. Orchard provides a few built-in shapes that you can use to add that extra bit of awesome to your modules. Today, we’ll look at the Pager shape, and I’ll demonstrate how you can add it to your module’s admin interface.

The Pager adds page numbers and back/forward controls, which makes it easier to navigate through long lists of items. It looks like this:

Or, if you have a few more items…

Neat! So how do we use it? First lets assume we have a module that provides a controller, which renders a list items on to a page in the admin dashboard. In this example, we’ll start by creating a controller that shows a list of all RouteParts on the site, and then add paging.

Our controller looks like this:

[Admin]
public class RoutesController : Controller
{
 
    private IOrchardServices _orchard;
 
    public RoutesController(IOrchardServices orchard)
    {
        _orchard = orchard;
    }
 
    public ActionResult Index()
    {
        var routes = _orchard.ContentManager.Query<RoutePart>()
                                                .List();
        var list = _orchard.New.List();
        list.AddRange(routes.Select(r => _orchard.ContentManager.BuildDisplay(r, "SummaryAdmin")));
 
        return View((object)list);
    }
}

This also has a view:

@model dynamic
@{
    Layout.Title = "List of RouteParts";
}
<fieldset class="contentItems bulk-items">
    @Display(Model)
</fieldset>

All we are doing here is getting a list of RouteParts and displaying their SummaryAdmin shapes. This is almost a less interesting version of the content items admin menu section.

The pager shape is really quite simple. When it is displayed it renders itself as a drop-down list (for setting the page size) and a few buttons to skip back/forwards or to a specific page. Selecting a page size causes a POST request to the current page, with pageSize and page parameters. Pressing one of the buttons causes a GET request to the current page, with the same parameters. Both of these can be represented by the PagerParameters object.

So, we’ll need to split our action method into two to handle each request. We also need to use the page index and page size parameters to restrict the number of elements returned via the view.

[HttpGet]
public ActionResult Index(int? page, int? pageSize)
{
    return Index(new PagerParameters
    {
        Page = page,
        PageSize = pageSize
    });
}
 
[HttpPost]
public ActionResult Index(PagerParameters pagerParameters)
{
 
    var routes = _orchard.ContentManager.Query<RoutePart>()
                                        .List();
 
    // Create our pager object and it's shape
    Pager pager = new Pager(_orchard.WorkContext.CurrentSite, pagerParameters);
    dynamic pagerShape = _orchard.New.Pager(pager).TotalItemCount(routes.Count());
 
    // Generate a list of shapes, restricting by pager parameters
    var list = _orchard.New.List();
    list.AddRange(routes.Skip(pager.GetStartIndex())
                        .Take(pager.PageSize)
                        .Select(r => _orchard.ContentManager.BuildDisplay(r, "SummaryAdmin")));
 
    return View((object)new IndexViewModel
    {
        Items = list,
        Pager = pagerShape
    });
}

Note that for the [HttpGet] method we are specifying the parameters separately, because we can’t duplicate the method signature for Index(). You could give the methods different names (e.g. in Orchard.Blogs.Controllers.BlogAdminController), and that might be a better idea for anything more complex – however I just find this easier to read.

Now all that remains is to add the pager to our view…

@model dynamic
@{
    Layout.Title = "List of RouteParts";
}
<fieldset class="contentItems bulk-items">
    @Display(Model.Items)
</fieldset>
@using(Html.BeginForm("Index", "Routes", FormMethod.Post))
{
    @Display(Model.Pager)
}

We add the Html.BeginForm() so that we create the form element required for the dropdown list to submit it’s POST request (since we didn’t give it any routing information).

It’s as simple as that! If you want to have a look at the full source, you can find it over on BitBucket. Happy Orcharding :-)

Ouch

Sure, I’m late to the party, but Ouch. I sure hope someone got fired for that one.

For those to whom it is not immediately obvious (myself included, this needed some quick man-paging): char * strncat(char *dest, const char *src, size_t n); copies n bytes on to the end of dest, whilst size_t strlcat(char * dst, const char * src, size_t siz) copies src to dst + siz. So, you get

dst = dddddddddddddddd
src = ssssssss
siz = 8
 
-> ddddddddssssssss

instead of

dst = dddddddddddddddd
src = ssssssss
n   = 8
 
-> ddddddddddddddddssssssss

In Rasmus’ defence, strlcat() and strncat() are pretty similar. What is unforgivable is that they don’t appear to run any unit tests when a new release is built.