As I had mentioned previously, I spent some time recently creating a control that would provide a facility to allow users to rate blog content (posts, comments, stories, pictures, you name it) and provide their own two cents. This control is presently implemented on my own blog as you can see. I’m making a few late breaking changes and creating the documentation. When completed, I will post it here for use on your own .Text blog if you’d like. If you simply MUST have it sooner, contact me and we’ll get it set up.
Getting the control implemented on a .Text site wasn’t extremely easy, but it wasn’t difficult either…you just have to know what to do. If you recall, the entire control (and its associated pages) is encapsulated within a single assembly: Devstone.Web.Blog.Controls.Rating.dll. This enables you to deploy the control to your blog by simply dropping the .dll in the \bin folder, tweaking the web.config, and running a database script (which simply adds a table and a few stored procs).
I have not tested this with .Text versions other than 0.95.2004.102. Also, my blogs have been the multi-user/community blogs rather than a single-user blog, but I imagine that getting it setup on a single-user blog would be pretty painless and follow much of the same procedure.
And now for the nitty gritty...
There are two components to the rating control: a Rating WebControl and a Rating Page. In order for the server to process requests I decided to handle the requests using an HttpHandler (technically, an HttpHandlerFactory and an HttpHandler for the dynamic images).
Within IIS I mapped the .dspx extension to the aspnet_isapi.dll, checking to not enforce that the file exist (because it doesn’t exist in this case) and allowing the verbs GET and POST. The .dspx extension is of my own creating (meaning Devstone Server Page).
Then I updated the web.config file. Some care had to be made here. .Text usurps ASP.NET in how requests are handled by defining its own suite of HttpHandlers depending on how the client request comes in. Therefore, I could not add my handler to the <httpHandlers /> section as one would traditionally do – I tried and got erratic results; sometimes it worked and other times it didn’t. Instead, I had to add my own <HttpHandler /> to the HandlerConfiguration/HttpHandlers node.
In fact this is the trick to making the whole thing work. You just have to make sure the regular expression is valid. And because I’m using a ‘Factory’ rather than ‘Handler’ to handle the requests my statements ended up looking more or less like this:
<HttpHandler pattern="^(?:/(\w|\s|\.)+/img/\d\.\d{2}/(?:Star|Dot|Bar)\.dspx)$" type="Devstone.Web.Blog.Controls.RatingHandlerFactory, Devstone.Web.Blog.Controls.Rating" handlerType="Factory" />
<HttpHandler pattern="^(?:/(\w|\s|\.)+/rate/(?:Star|Dot|Bar)/[12345]/\d+\.dspx)$" type="Devstone.Web.Blog.Controls.RatingHandlerFactory, Devstone.Web.Blog.Controls.Rating" handlerType="Factory" />
If I had created HttpHandlers, rather than HttpHandlerFactories, I would have specified a handlerType of ‘Direct’. Also, of note: depending on how your blog is set up, the regular expression will differ. http://blog.devstone.com/ for example, is at the root so my regex starts ^(?:/(\w|\s|\.)+/…. If the blog is rooted in a virtual directory, your regex may resemble ^(?:/\w+\/(\w|\s|\.)+/…
Additionally, my control relies on a few custom configuration values that I added to the <appSettings /> section for ease – though I could have just as easily created my own configuration section.
Once those steps were accomplished, all I had to do was add the <%@ Register %> directive to each of the .ascx controls on which the control would be rendered. For example, I wanted the control to sit along side each post on the blog’s main page. Therefore, I opened the Day.ascx control and added the following lines:
<%@ Register tagPrefix="devstone" namespace="Devstone.Web.Blog.Controls" assembly="Devstone.Web.Blog.Controls.Rating" %>
<%@ Import Namespace="Dottext.Framework" %>
<%@ Import Namespace="Dottext.Framework.Components" %>
Then navigated down to within the <ItemTemplate /> element of the DayList Repeater control and added the following line of code:
<devstone:ratingsummary id=rs runat=server alignment=right postId="<%# ((Entry)Container.DataItem).EntryID %>" postLink="<%# ((Entry)Container.DataItem).Link %>" />
That’s all there is to it. This associates the proper id and url with the rating control. The link isn’t strictly necessary, but is included as a courtesy for when the post is rated, the owner of the blog is sent an email with a link to the post within it.
There are a slew of other properties that can be assigned which I will discuss in the next post when I provide the final documentation and product for download.