Sitefinity 3.0 is much more than just a CMS. It’s flexible, modular and open architecture let’s you build on top of Sitefinity virtually any kind of web application. In the first post of this series, I’ll discuss how could one approach building a Digg-clone web application. It’s actually much simpler than you may think. So… here we go.
In it’s most rudimentary form, this application let’s users submit links to web pages and describe the linked story with short description and a title. Other users then, have the option to vote for or against the submitted link / story. When story is first submitted it’s put on one page; we can call it “New stuff”. The very popular stories (stories a lot of users voted for) get on the other page; this page we can call “Popular stuff”. And that’s it… we’ll leave all the bells and whistles out for the moment being.
Short features list
- Users that will submit links, vote for or against the links and comment on stories need to be registered users
- Registered users have an ability to enter the title, short description (500 characters) and link to the story they’d like to submit
- Each submitted story should have a page of it’s own
- New stories are listed on the page “New Stuff”
- Popular stories are listed on the page “Popular stuff”
- Each story has buttons to vote for it or to vote against it. Only registered users can click on those buttons
- One user can vote only once for the story
- Users can comment on submitted stories on the story’s individual page
- Stories appear on the “Popular stuff” page when they reach 50% of the points that average (last 100) popular stories have and they are ordered by the date and time of “becoming popular”. So if last 100 stories have 10 votes on average, this means that when story gets 5 votes it becomes popular.
- At any time there can be only 1000 stories in “New Stuff”. If the page does not make it to be popular in the period when 1000 new stories are submitted it will be deleted.
- Stories with 100 negative votes will be treated as spam and deleted.
Basic implementation idea
Since we don’t need administration for this kind of web application (users are doing all the work), we can implement the application solely by using custom web controls. Here is a simple chart of controls needed for this application.
So as you can see, I’ve divided controls in three categories. First is the “Digg-clone” essential controls. These controls are required to archive the basic functionality of this application. We have :
- Submit story - this is a very basic form that lets user enter title of the story, description of the story and link to it. All we do here is save the story in the database and that’s all.
- Stories - this is a control that lists all the stories. By altering the datasource we can use this control to display stories on “New stuff” page or alternatively on “Popular stuff” page. Alongside each of the stories we’ll display the number of votes story received and buttons “Vote for” and “Vote against”. If vote is cast, we’ll save that to database.
- Single story - when user clicks on the story in the Stories control he’ll be redirected to a page which holds our Single story control. This control displays all the info on the story, the link to the actual story and list of comments user made on this story.
- Comments - very simple control which is basically a form that let’s user leave the comment on the story. Comments are stored in the database after user enters it. Sitefinity actually has CommentsList control which you can use to display list of all comments and as a form for entering a new comment. Take a look at Telerik.Cms.Engine.WebControls.CommentsList class. If you prefer, you can use that control instead of building your own.
Next we have membership controls, which are basically typical ASP.NET 2 controls. We do have to provide a way for users to register, log in and log out.
Finally, we have some optional controls for Digg-clone application. You can create those, but don’t really have to. It’s up to you.
- Top 10 - this control simply shows the top 10 stories that are currently most voted for. We could add a condition that top 10 stories cannot be older than 30 days just to make it more up to date.
- Voting Structure - this control has two modes or perspectives. One is to display all the users that voted for one story, other one is to display all the stories user voted for or against. Though not essential, it’s one of those hype social kind of things.
And here is the point where Sitefinity API kicks in! Take a look at following diagram that will show you that all you really need to do is extend Sitefinity with only one database table and several methods. Everything else is there for your convenience.
Because the submitted stories are nothing more than content we’ll treat them as such and use Telerik.Cms.Engine assembly which handles most of the work for GenericContent, Blogs and News modules. For the extra info (such as link to the original story, number of votes for and against the story) we’ll use powerful MetaData class which allows us to add arbitrary information related to the specific content (for example in News module that’s how we store “Source” information).
What you are left to do is implement the code to handle User Info data and create a Nolics dbclass for holding this info in database. In the User Info table we’ll hold data on which user voted for particular story and how did he vote.
So, in addition to creating web controls you’ll have to add assembly that will handle data. Let’s call that assembly Stories.Data
In this assembly you need classes UserInfo.dbclass and DefaultStoryProvider.cs. First class as I have said is responsible for persisting UserInfo data, while other class should inherit from Telerik.Cms.Engine.Data.Providers.DefaultProvider class. That way you’ll be able to access methods such as CreateContent, SaveContent, GetContent, GetMetaData etc. You would need to add only methods such as CreateUserInfo, UpdateUserInfo and such.
Ideas for improving the application
- Implement voting for or against the comments
- Create story categories
- Add tagging for stories
- Extend application to other medias (photos, videos, podcasts…)
List of Sitefinity API members and namespaces you should use to accomplish this task
Namespace : Telerik.Cms.Engine
- IContent - content interface
- IComment - comment interface
- IMetaData - meta data interface
Namespace : Telerik.Cms.Engine.Data
- Providers.DefaultProvider - use it to work with any content or comment related data
- CreateContent - creates new content
- SaveContent - saves new or updated content
- DeleteContent - deletes content (use this to delete spam)
- GetContent - various overloads for getting single content, list of content with paging, filtering sorting etc.
- CreateComment - creates new comment
- DeleteComment - deletes comment (spam for example)
- GetComment - gets comments
- SaveComment - saves new or updated comment
Namespace : Telerik.Security
- SecurityManager - use it to work with members (register, log in, log out)
- Though you can use common ASP.NET way of dealing with security, by using SecurityManager you have an option to easily change Membership Provider at later stage. Also, there are several helper methods in this class.
So, let’s quickly review what we need to do to get our digg-clone application up and running.
- Create needed web controls for user interface
- Create Stories.Data project. Add classes UserInfo.dbclass and DefaultStoryProvider.cs which inherits from Telerik.Cms.Engine.Data.Providers.DefaultProvider
- Register Stories provider (new cmsEngine provider) in web.config (you can take a look at the Blogs provider to see how this is being done)
- Add metafields for your new Stories provider (you can also take a look at how is this done in case of blogs)
- Drop the controls you’ve created on pages and voila!
If you have any questions, suggestions or advice regarding this post please leave the comment or drop me an email at firstname.lastname@example.org