We’ve been hard at work over the last month working to refactor Oxite. We received a lot of community feedback about how we organized the code in Oxite. I don’t want to go into too much detail, but want to be completely transparent (I’m from the Channel 9 team, would you expect anything less?) about how Oxite came to be. Oxite was a side project by a couple of us that just thought it would be cool to release some of our code that was reusable, showed off the ability to control your markup 100% and was more than a sample (something people could actually ship on if they wanted to). It obviously got expanded into more than that, but just wanted to share a little behind the “how, when, who and why” of Oxite. For a more in-depth explanation, check out Duncan’s post.
Back to the community feedback, although some of it was taken a bit too far, overall the community was right and we decided it was necessary to begin a large refactor to get our code more inline with ASP.NET MVC. Sampy has a post (Part 1 and Part 2) about the architectural changes we’ve made in this release of Oxite. You should check out. He also started an Oxite Architecture page on CodePlex. I don’t think there’s a single line in Oxite that hasn’t been touched. As with all projects, we will continue to evolve it moving forward. We’ve discovered a few places where our current architecture has a few things that don’t work out perfectly. In the next release we will address some of this, but they will be much smaller changes than in this release.
What We Refactored
Besides "everything", well, we added dependency injection (much needed). We already had things like our Controllers setup for this, we just hadn’t taken the final step to add it. Now that we are using it in lots of places, and things are much simpler and easier to setup now. We get the added benefit of being able to replace anything that is loaded through DI with a web.config (or code) change. You can replace everything from our Routes to Controllers to ActionFilters to Repositories. Be sure to read Sampy’s post. He has a section on DI.
The model has also been cleaned up to make more sense. Before, we were using interfaces for everything to get around LINQ to SQL building it’s own concrete types, but this was problematic. Now we just have our own concrete types. Unfortunately, because we can’t easily manipulate LINQ to SQL with different query options before the statement is executed and still get our types back, we have to project them to our types. A little painful, but not too bad.
Another big complaint we addressed was that our Controller Actions were being used like the Page Load method in WebForms. We were brand new to MVC when we started Oxite and it was an honest mistake that I think those new to MVC will make. With the model and repositories cleaned up it and the addition of ActionFilters, we were able to get almost all of our Controller Actions shrunk down so they follow SRP.
We’ve also added quite a few ActionFilters that help us build up the ViewModel and fill things out for the Controller Actions for us. These are where all our code to do additional things on the page have gone like filling in the sidebar data. We also created an ActionFilter registry class that Sampy will probably explain more soon, for specifying when ActionFilters are executed.
The last major thing I can think of that we cleaned up were the Views. To be clear, what the Views produced was always very clean. What I mean is we cleaned up the code and markup in the Views to use more HtmlHelpers when appropriate. At the same time we also split more views apart and rearranged where they live to make more sense and to ensure we don’t have repeated markup/code anywhere. This helps make skinning easier.
With all this refactoring, we still managed to stabilize current features, add new features and simplify deployment. The refactor was our only goal for this release, but some of us really care what features Oxite has and want to improve on it with every release. Lot’s of late nights, but well worth it. Now that we’re all also running Oxite as our blogs we will continue to find/fix bugs and add new features. Let’s go over old and new features.
So we’ve got all the basics you’d expect in a blog:
- Content pages
- RSS and ATOM feeds everywhere (All up, Blog, Tag, Comment, etc)
- Trackbacks (sending/receiving) and Pingbacks (receiving)
- Email subscriptions
- Metaweblog API support (use Windows Live Writer, etc to post to Oxite)
- Web admin
- All up dashboard
- Manage site
- Manage areas (blogs)
- Add/Edit Posts/Pages
- Manage comments
- BlogML import
No need to go over those in detail since they’re very standard these days. We also have some other features that are either unique to Oxite or are just nice to have and not necessarily in every blog engine. I’ll let you be the judge which are which.
Background services are basically classes that are wrapped by an executor that calls a Run method in a timer so it’s run on a separate thread. You might be asking why a web app would need this. Most other blog engines don’t do this, why Oxite? Personal preference around user experience is the short answer. The slightly longer answer is that we think it’s a bad idea to hold up a page request to go off and do something intensive or dependent on a potentially long running task (like post to another website). I’ll use the two background services we ship with as examples of what I mean by that: SendTrackbacks and SendMessages. SendTrackbacks is a service that simply takes any outbound trackbacks that were generated from creating or editing a post and sends them. You say, "This seems like a really simple task. Why not just have that happen when you add/edit a post?" Good question. It IS a really simple task. There’s not much code in the service. However, the work done in that service can take a while and is dependent on the sites that you linked to. Submitting a new post could be infinitely held up by all those requests and only gets worse the more sites you link to (to get a response back from them). SendMessages exists for the same reasons. It’s purpose is to take a generated list of emails and send them through SMTP. Again, super simple and barely any code at all, but if you have a lot of people with email subscriptions set up or your SMTP server goes down or is slow this could take a really long time. Background services move the load to the background so the user’s request isn’t held up.
Multiple Site Storage in Single Database
This is mostly a feature that we’ve found important over the years to what we do, but thought it would be helpful to others. In the web.config <appSettings> you can specify a "SiteName" that is a unique string in the database for the current application’s instance name. Since all posts, content pages, blogs, etc are all scoped by that name, you can store many sites in the same database. This may or may not be useful depending on your hosting situations.
ASP.NET MVC is perfect for skinning. We built our own little skin engine that basically just helps the view engine decide where to look for WebForms, Styles and Scripts. If you just want to create a skin just with CSS that’s super simple. If you want to create a skin with CSS and override some of the default Views, that is also really simple. Check out Nathan’s page on CodePlex about How to Skin Oxite.
Web Standards Compliant
From day 1 when we started building the MIX Online site we found that ASP.NET MVC was great for controlling your markup and have taken advantage of that in Oxite to ensure we are XHTML 1.0 Strict compliant as well as having our CSS, RSS and ATOM validate. Go out and compare Oxite to other blog engines and see how well or not well they validate. Take it a step further and compare Oxite to major websites out there. Fun! Beyond being compliant with web standards our markup is semantic. This is just a good thing to be overall, but can also make skinning much easier as the classes properly describe the content they are attributed to. Hats off to Nathan! Be sure to check out Web Standards: Where the ROI is by Molly Holzschlag and Web Design from the Gut by Nishant Kothary.
Now that we’ve got most of the refactoring done and are more solid across the board, what’s next? Lots! Our team can’t devote time to working on Oxite unless it is related to one of our projects (like it was for MIX Online). It just so happens this month’s work relates to Oxite for our next project so we will be making improvements. We will be creating the new Session Browser for MIX and it will be running Oxite. Out of this, the new feature we’ll be adding is files. This was one of the few features we had in the first version of Oxite, but had to cut. It’s coming back in the next release because we need it for the session browser. This includes being able to upload new files and associate them (or existing files at any URL) with a post. We think that’s valuable in a blogging platform (and of course for us) so we’ll be adding it for the next release. We will also be refactoring a few more things as we go. On a personal level here are the things we will be working on in our spare time:
Plugins will allow a developer to build new functionality on top of Oxite and allow someone running Oxite to drag-drop-run this new functionality. Some of you may have noticed there are some plugin classes in Oxite today. These were just the start and we ran out of time to finish that feature. We will finish them off in the next release to make it super simple to tack on little pieces of functionality (everything from adding Routes, ActionFilters and Controllers to keeping track of settings for the plugin and making them installable) to Oxite.
We will be adding the ability to create subfolders under a skin with addition Styles and Scripts (and potentially other subfolders for other sub-variations) to create variations of skins. These variations will "inherit" all the Styles and Scripts from its parent skin. We’ve found lots of skins that would look great with tweaked colors, fonts, etc. At the same time, we will also be modifying the site settings page to make selecting a skin and optionally a variation strongly typed (ex. dropdown lists).
Rich Text Editor (RTE)
Without a RTE in the web admin, it can be a bit difficult to craft your own HTML by hand. For now, we suggest you use something like Windows Live Writer to post to Oxite. Eventually we’d like to add RTE to the plugin side of things so you can decide which RTE you’d like to use. We’d also like to find an RTE that we can ship out of the box with Oxite, but it’s difficult to find one with a license that agrees with MS-PL.
Trackback validation service and trackbacks display
We’re currently keeping track of inbound and outbound trackbacks, but we don’t currently validate that received trackbacks are valid (ex. did the site actually link to you or is this just spam), nor do we show trackbacks anywhere in the default skin. This is what we’ll be implementing.
This is an area we dropped the ball on with this version of Oxite. Our "authorization" model right now is basically "can you log into Oxite? Ok, then you can do whatever you want." For most this is fine since you’re usually just using Oxite for a single blog. In the cases where you’d like to have more than one blogger on your site (family website, company website, etc) this is crucial to be able to set permissions to blogs and other stuff and we will be adding it back.
Content Page Management
There is currently no UI for displaying what content pages are available on your site (other than the dropdown list for picking which page is the parent of the current page you’re adding/editing) so you can move/remove them. We haven’t figured out if we’re going to use a tree view or something else for this, but it is needed and has already been brought up in the community.
Other View Engines
We are investigating other view engines. WebForms in MVC is great, but sometimes it isn’t a great fit, especially when you want a designer to work on the views. Spark is one of them that we’re investigating. If anything, we will at least get back to following MVC and allowing other view engines to be registered and used.
Because of our good markup that we render, viewing an Oxite site from a phone is a decent experience. It is readable. We want to do more. You should be able to control your markup without a lot of work that gets sent to phones and this is what we’ll enable.
This list will take us a bit. If I had to guess I’d say 2 or 3 months to finish off that list (there will be many release in between). Keep in mind this is just as we have time (an evening here and there) and it’s possible and likely that this list will change over time. I’d love to hear what features you all think are important.
Where to Get Oxite
If you’ve read this far and want to checkout Oxite, please visit Oxite on CodePlex. The latest release can be found here. Be sure to go through the Setting up Oxite page as there are dependencies to run Oxite. If you end up running it publicly somewhere, let us know and we’ll add your site to our list of sites running Oxite. If you create a skin you want to share it, let us know and we’ll post it up for others to find. If you have feedback for us or just want to discuss Oxite, start a discussion on CodePlex. If you think it’s lame that I use the default skin for Oxite (I do and it’s lame), make a hot looking skin and I’ll use it for my site and give you credit!
How to Keep Up on Oxite
Many of us are on Twitter and we talk about Oxite. You can follow me on Twitter here. My blog will also be a good thing to follow as I’ll be talking about Oxite as we progress. Oxite on CodePlex will also be a great place to watch since they have discussions, an issue tracker and RSS for Releases.
I have some other "hidden" features I’m going to blog about soon, but what do you want to see blogged about next? What isn’t clear in Oxite? What’s hard to use? What things do you want to learn how to customize? Any other questions you have, please leave a comment and I’ll address them.