Archive for May, 2007

Sitefinity Meets Web 2.0 (part 2) : Dating site

Posted on May 28, 2007. Filed under: Pushing the envelope |

Sitefinity Meets Web 2.0 - Dating site

Undoubtedly, it takes a programmer to write about dating and romance, while using diagrams, classes, methods… Furthermore, it is also only a programmer that won’t be considered pervert if writes about dating and titles one of the sections “Basic implementation idea”. So without further ado…

This post will describe how you can use Sitefinity to roll out your own dating site.

Basic idea

As complicated as it may sometimes seem, dating is nothing more than two people meeting each other. So that’s the premise we’ll use for our application as well. Each user that wishes to find a date through our site needs to create his/her own profile. Profile is a collection of arbitrarily important facts about that person (ranging from very important such as who is the person looking for – man or a woman – to trivial facts as preferred drink). For each profile we are going to create an actual web page, so each user can have a unique url.

We’ll create two templates that will be used for creating user pages. One for female users and one for male users.

All profiles will be accessible only to other users with other profiles and they will be able to filter out potential dates on certain criteria.

Short features list

  • Each user creates a profile in order to participate in dating site
  • Each profile has it’s own page
  • To create a profile users need to supply following information :
    • First name ( required )
    • Sex ( required )
    • Sex of a person user is seeking ( required )
    • Birth date ( required )
    • Picture ( required )
    • Number of optional information : height, weight, body type, eye color, hair, smoking, drinking, education, employment status, marital status…
  • Users will be able to send private messages to each other. That will be the only way for two users to get in contact, since no email addresses or phone numbers will be displayed.
  • Users will be able to browse profiles of other users by filtering the preferences

Basic implementation idea

Similar to the Digg-clone application in this application we don’t need administrative controls, since users are doing all the work. Take a look at the simple diagram showing the components we’ll need to build in order to create dating site.

Dating site components

Let me start by explaining the web controls that we need to create.

  • User Profile – this is a key web control of this web application. This control we will implement as a DetailsView control. The view mode will be accessible by all users who have their own Profile. The edit mode will be accessible only by the user that owns the profile. And the insert mode we will use when user is creating the profile for the very first time.
  • User Messages – this is the control that will allow users to communicate among each other. To protect each user’s privacy we won’t display email or phone on the user profile and initial contact will be possible only through the User Messages control. This control has two modes : a) post a message and b) read / reply / delete messages. To the owner of a profile this control will appear in b) mode, while to other users it will appear in a) mode.
  • All Profiles – this is a control that will display all the profiles in RadGrid control. Profiles can be sorted, filtered by specific criteria (such as age, sex, smoking etc.). By clicking on a particular profile user will be taken to the individual page of that profile.

Two other things we need to create are templates for a man profile and woman profile. In case you are unfamiliar with templates and how to create them you can consult a developer manual (I’ll write a blog post on this topic this week as well). So, when user creates a profile, we’ll create a new page in Sitefinity and assign appropriate template to that page based on the user’s sex.

Creating a data provider

Since we are working with a structured data (we can’t just let users type whatever they feel like, we need a very specific info about them) we need to create a data provider for user profiles. Consider the following diagram to see how are we going to work with data.

Dating site - data provider

UserProfile.dbclass is a Nolics implementation of database table that will hold all information regarding a user profile. As you can see there is also a PageID field in this table. That field holds the id of Sitefinity page where this User profile will be located. But that will also gives us a reference other way around. When user opens a particular page we will simply search all the profiles to find a profile whose PageID matches the id of that page and load that profile in User Profile DetailsView control.

Note that all the pages will be exactly the same (they will look like a template). All the web controls will be added directly to the templates. Based on the page (and it’s id) we will just bind DetailsView (User Profile) and RadGrid (User Messages) to different data.

Since we can dynamically set the template of each page, when we create a page that will hold user’s profile we’ll take into account the sex of user and set the appropriate (man/woman) template for that page.

UserMessages.dbclass is a Nolics implementation of database table that will hold all the messages users exchange. All the fields are pretty obvious, except maybe ParentMessageID. This we’ll use for replies so that we can group messages and replies to be more user friendly.

And the very least thing we have on the diagram is Telerik.CMS namespace. This namespace we will use to create Sitefinity pages when user creates a profile and to set templates.

In case you are not sure how would you create Data Provider (it should be an assembly, .dll file) you can check how is Contacts.Data assembly implemented in following posts (there is also a link to download the project in the second post) :

Ideas for improving the application

  • Implement “hot or not” voting on each profile
  • Create an algorithm that will attempt to match “perfect” couples and give suggestions to users
  • Provider users with an ability to post video clips on their profiles

List of Sitefinity API members and namespaces you should use to accomplish this task

Namespace : Telerik.CMS

  • ICmsPage – interface that defines cms page
  • IPage – more abstract page interface implemented by ICmsPage
  • IPageBase – interface that descibes any page (not necessarily cms page) in Sitefinity. Implemented by IPage interface
  • CmsManager – class with methods for working with pages and templates

Summary

If you are about to create this application you can learn a lot by examining the JobsIntraSite module that comes with Sitefinity. Obviously, you would not care about the ControlPanel and CommandPanel controls of JobsIntraSite module since you don’t need administrative access, but you can see how data provider (Telerik.Samples.Jobs.Data) is implemented there and also learn how to work with Nolics from declarative code which you will use for all of your web controls.

Good luck!

 

Read Full Post | Make a Comment ( 3 so far )

Working with complex properties in Custom public controls (WebTypeEditor)

Posted on May 25, 2007. Filed under: Tip of the week |

When working with Sitefinity, specifically with public web controls (such as Image of Posts list) you may have noticed some properties that have a “Select” button next to them. Those properties (we’ll call them Complex properties for the purpose of this post) have one thing in common : It is impossible or very hard for the user to type in the value of those properties so another window opens and let’s user visually determine the value of that property.

To show you how you can implement those complex property editors, I’ve created a short project called Quotes. The project has two controls :

  1. QuoteList – public control that displays all quotes inside of one category of quotes (this control has a complex property Quotes, which can be edited in QuotesSelector control)
  2. QuotesSelector – web editor control that let’s user select which category of quotes to display

Take a look at the following screenshots to get the idea of the functionality that’s being described :

Complex property

Complex property editor

Though the project is available for download and it is commented, let me just simply explain the concept.

You create a custom control as you would usually (same principle applies if your custom control is part of module as well) and then you set up a complex property just as any other you would. So my complex property is named Quotes and it’s of type string. The value of this property is the key of the dictionary that holds different categories of Quotes. Since users don’t know which categories of quotes are available I wanted to provide them with a new control that will let them choose among various Quote categories. In order to attach a Web Editor to a property I needed to add an attribute. This is how the property is defined in QuoteList control :

[WebEditor(“Sample.Quotes.QuotesSelector, Sample.Quotes”)]
public string Quotes
{
get
{
return this.selectedQuotesCategory;
}
set
{
this.selectedQuotesCategory = value;
}
}

As you can see I’ve added WebEditor attribute and set it to QuotesSelector control, the other control in my project.

QuotesSelector control is just another custom control where I can do whatever I please, but with one important property! The overriden Value property of WebUITypeEditor is the value that will be returned to the QuotesList Quote property when user clicks “I’m done” button. So, one central purpose of QuotesSelector control is to set the it’s Value property. How will this been done really doesn’t matter, though should be user-friendly as possible :).

The Sample.Quotes project you can download here. (Note : I’ve used the fake data source which is implemented in QuotesDat.cs file)

p.s. when you upload Sample.Quotes.dll control through page editor Both controls will appear. Since you don’t want users to be able to drag QuotesSelector control, go to web config and delete QuotesSelector from toolboxControl section. Optionally set section of QuoteList to “Quotes”.

Read Full Post | Make a Comment ( 2 so far )

Quick question!

Posted on May 22, 2007. Filed under: Uncategorized |

VB.NET questionDear readers,

I’m sorry that I haven’t asked this question earlier, but better late than never…

Would like me to post some samples in VB.NET? So far it was only C#. Please leave a comment if you’d like some VB.NET samples. If you show the interest, I’d gladly provide you with VB.NET samples as well.

Thanks,
Ivan

Read Full Post | Make a Comment ( 2 so far )

Building a module for Sitefinity (part 6) : Anatomy of a web control

Posted on May 22, 2007. Filed under: Building a pluggable module |

Anatomy of web controlGenerally, we can say that all web controls you are going to build for Sitefinity modules have several things in common. In this post I will explain how I’ve approached building a ControlPanel control for Contacts module. Once that is explained everything else should come pretty easy to you. At the end of this post you’ll find a link to the project so you can download it and examine (I’ve commented the project rather extensively).

There are two cornerstone ideas we have when we build any kind of control :

  1. Appearance of control is defined through a template. To control it should make no difference how the template is created
  2. Working with data is done through a manager class. It should make no difference to control how is data being stored, that’s up to provider.

Take a look at following diagram to get a high overview of how Web controls are built in Sitefinity.

Web control diagram

Working with controls

On the left we have Web Control (blue) which represents ControlPanel in this example. This control acts as a wrapper control for the actual controls of ControlPanel. The child controls being (if you forgot how control panel should look like, take a look at this mockup Contacts module > View mode) :

  1. Add new contact – when clicked Control panel should switch from list mode to insert mode
  2. Contacts grid – Rad Grid that lists all the contacts
  3. Contact Editor – this control serves a purpose of adding new contacts or editing existing contacts (if you forgot, this is how this control looks like Contacts module > Insert / edit mode)

In order to allow designer / user experience expert to modify the look and feel of the controls without messing with the code and recompiling we load controls from template. This is where the GenericContainer kicks in. We are always going to instantiate the template inside a class that inherits from GenericContainer. Generic Container class allows us to define controls that are absolutely necessary for ControlPanel to be working (required controls), but also allows us to define the controls that can be there, but are not necessary (optional controls). So if a template creator forgets to add a Button control with the id of “addNewContact” an exception we’ll be thrown saying that template is missing a required “addNewContact” button. By using GenericContainer class we have an easy way to make a contract between a programmer and designer.

Template creator has two options when it comes to creating a template without coding. One is to create an user control and set it’s path in the web.config provider or he can declaratively create template. Note that it is only possible to create declarative template if the ControlPanel is added to the page or user control declaratively as well (it’s obvious that if we add ControlPanel dynamically we can’t create template declaratively).

Third option for creating a template is default template, class that inherits from ITemplate. You should always implement default template because it is possible that Page object will not be accessible at one time or another (Design) and you don’t want the control to crash at that moment.

If all this sounds messy, take a look at the diagram once again, download the project and examine the code, and then reread it again. This whole idea is actually much simpler than it sounds.

Working with data

In order to keep our control as flexible as possible, all the work with data will be done through manager (ContactsManager) in this example. Depending on how you initialize manager (without the provider name it will use ‘DefaultProvider’ or with the actual name of the provider) manager will decide which provider to use to work with data.

This, for example, allows you to move your data from Sql Server to XML without ever modifying the Web controls. All you need to do is create a new Data provider and initialize manager with the name of new provider.

Few last words

I’ve just explained the logic behind creating the controls. Understanding this logic should ease your decisions regarding where to create controls, how to bind controls to data and such. The detailed explanation you can get by examining the project, since I’ve commented all the crucial parts. Once again, if you have any questions, don’t hesitate to ask. Nothing would make me more happier that a request from you to write a blog post on a topic that has not be understood cleary 🙂

Next steps

Since we’ve covered most of the topics so far, I won’t be explaining the project step-by-step anymore, but will point out important aspects. So from now on, I’ll be working more on the code and comments… while in posting I’ll let you know what has been added so you can see how to whole thing is rolling out.

YOU CAN DOWNLOAD THE PROJECT HERE

One more thing, once the module is completed I’ll make the entire solution (with Sitefinity Community Edition) available for download.

Read Full Post | Make a Comment ( 4 so far )

Sitefinity meets Web 2.0 (part 1) : Digg-clone application

Posted on May 19, 2007. Filed under: Pushing the envelope |

Digg-clone application with Sitefinity 3.0

 

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.

Basic idea

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.

Digg-clone web controls

So as you can see, I’ve divided controls in three categories. First is the “Digg-clone” essential controls. These controls are required to achive 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.

Digg-clone reuse

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.

Summary

So, let’s quickly review what we need to do to get our digg-clone application up and running.

  1. Create needed web controls for user interface
  2. Create Stories.Data project. Add classes UserInfo.dbclass and DefaultStoryProvider.cs which inherits from Telerik.Cms.Engine.Data.Providers.DefaultProvider
  3. 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)
  4. Add metafields for your new Stories provider (you can also take a look at how is this done in case of blogs)
  5. 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 iosmak@gmail.com

 

Read Full Post | Make a Comment ( 1 so far )

Sitefinity meets Web 2.0

Posted on May 17, 2007. Filed under: Pushing the envelope |

To break the monotony I’ve decided to make a short break from pluggable module series (though that series we’ll continue parallel with this new one) and give you the list of ten Web 2.0 applications you can build with Sitefinity! Some of you may scratch your head now and wonder if I was celebrating official release of Sitefinity 3.0 a bit more than I should of and if the common celebratory substances remaining in my body are making my blogging just little too creative. Nope. As I will show, Sitefinity 3.0 is much more than just yet another CMS.

Sitefinity meets Web 2.0

This, as I have already stated, will be yet another list (I’ve got hooked on lists after reading Nick Hornby’s High Fidelity).

Ten Web 2.0 apps you can build with Sitefinity

This is not a definite list, but I like number ten almost as much as creating lists. I also like popcorn, but that fact may be behind the scope of this post 🙂

So, here we go :

  1. Digg-clone application
  2. Dating site
  3. Photos sharing site
  4. Team collaboration application
  5. Feed aggregator
  6. Personal organizer ( TO-DO list + Calendar)
  7. Blogging platform
  8. Job board
  9. Social networking site
  10. Wiki

Now, don’t get me wrong. You will have to do some programming, but with Sitefinity you are more than half way done which ever of the listed applications you are about to build.

Every day, for the next ten days I will explain the rudimentary idea of how you could approach building one of the applications. For each application I will provide you with the (hehe… here we go with the lists again) :

  • Basic idea
  • Short features list
  • Basic implementation idea (user controls, modules, web controls…)
  • Ideas for improving the application
  • List of Sitefinity API methods and namespaces you should use to accomplish the task
  • Application diagram

So stay tuned, tomorrow I’ll kick it off with the Digg-clone app.

Read Full Post | Make a Comment ( None so far )

Building a Module for Sitefinity (part 5) : Module structure

Posted on May 16, 2007. Filed under: Building a pluggable module, Projects |

The Contacts pluggable module will be made of two assemblies : Sample.Contacts and Sample.Contacts.Data

The business logic and UI will be implemented in Sample.Contacts module, while the data access we’ll be done through the Sample.Contacts.Data assembly. Take a look at the following diagram to see the big picture :

Contacts module diagram

Sample.Contacts assembly

There are five main parts of this assembly :

  • Web controlsAdmin web controls that will provide a way for authorized users to work with contacts and Public controls that will display the contacts on the pages.
  • Contacts Manager – Web controls will work exclusively with Contacts Manager when manipulating data.
  • Contacts ProviderContacts manager will call the methods inside of a provider class. Since there can be more than one provider (Sql and XML for example) the Contacts Provider is an abstract class that the actual provider classes need to derive from. In addition to this, the Contacts Provider class will be used to retrieve various settings from web.config used by the module (like paths to external templates and such).
  • Both, Contacts Manager and Contacts Provider classes will get the needed settings from web.config by using Configuration classes.
  • Finally, we have Resources where all the messages and labels will be stored in case we decide to localize our module at later stage.

Sample.Contacts.Data assembly

There are four main parts of this assembly :

  • Contact (dbclass) – Nolics class that will define the database object for storing contacts and it’s Contact partial class that we’ll use to add some additional functionality
  • Department (dbclass) – Nolics class that will define the database object for storing departments and it’s Department partial class that we’ll use to add some additional functionality
  • Default Provider – This class derives from Contacts Provider abstract class and will actually implement all the data manipulation methods (such as inserting a new job, deleting a department etc.)
  • Resources – here mostly to hold error and exception messages in case we decide to localize the application at later stage

In the next post I’ll provide the link for the latest version of the project and describe briefly what’s been done. If you have qustions or suggestions, don’t hesitate to leave the comment 🙂

Read Full Post | Make a Comment ( None so far )

Liked it here?
Why not try sites on the blogroll...