+1-888-365-2779
Try Now
More in this section
Categories
Bloggers
Blogs RSS feed

In the mean time series (part 2): "Products" module - simple implementation with enabled comments

by Ivan Osmak

Ok, after short break with SiteActivity control, back to the serious stuff. Continuing the “In the mean time series”, we are making headway to the full-fledged products module. In this post I will demonstrate how to enable comments on our products module – module based on Generic Content.

NOTE: This sample has been created and built with Sitefinity 3.5 Service Pack 1, however it will work normally with 3.5 as well. For users running Sitefinity 3.2 the sample should work as well, though you will need to change the references and implementation of RadControls. You can take a look at the first two samples in the developers manual two see how the implementation was done for 3.2.

“Products” module – simple implementation with enabled comments

NOTE: In case you don’t think you need the instructions, you can download the sample code for this project from here and skip the reading.

The process of enabling comments is not much different than the one for enabling categories or tags. Again, we will divide our task in two parts:

  • Enabling comments functionality on the admin side and
  • Enabling comments functionality on the public side

Before we proceed, make sure you have at least set up the products module project like it was described in the introductiory article of this series.

Admin side – CommentsView

On the admin side, we have to enable the CommentsView command and provide the templates for the Comments functionality. Once we are done we will be able to access the CommentsView of Products module which will look like the one at the Figure 1:


Figure 1: CommentsView command on the left and CommentsView control on the right

CommentsView allows administrators to manage comments. Comments can be moderated, approved, deleted, edited and so on.

Let’s start by uncommenting the CommentsView button in the CommandPanel. Open following file:

~/Sitefinity/Admin/ControlTemplates/Products/CommandPanel.ascx

Now that you have opened the file, uncomment the two lines representing the CommentsView command:
<dt runat="server" id="commentsDt"><asp:LinkButton ID="commentsLink" Text="<%$Resources:Comments %>" runat="server" /></dt>  
<dd runat="server" id="commentsDd"><asp:Literal runat="server" Text="<%$Resources:CommentsDescription %>"></asp:Literal></dd>  
 
When done, your CommandPanel template should look like this (in case you’ve been following the whole series):
<%@ Register TagPrefix="cc1" Namespace="Telerik.Cms.Web.UI" Assembly="Telerik.Cms.Web.UI" %> 
<h2> 
    <asp:Literal runat="server" Text="<%$Resources:ExploreProducts %>"></asp:Literal></h2>  
 
<!-- panel which provides User Interface for working with multiple providers in Products module --> 
 
<div id="providersPanel" runat="server" class="provider SiteMapTools">  
    <cc1:LabelToolTip HelpBoxCssClass="HelpBox" ID="labelHelpBox1" runat="server" LabelMode="true" 
        LabelTargetID="providersList" LabelText="<%$Resources:ChangeGroup %>" ToolTipTitle="<%$Resources:Group %>" 
        ToolTipText="<%$Resources:AboutGroup %>" AlternateText="<%$Resources:AboutGroup %>">  
    </cc1:LabelToolTip> 
    <asp:DropDownList ID="providersList" AutoPostBack="true" runat="server">  
    </asp:DropDownList> 
</div> 
 
<!-- menu with various commands of CommandPanel --> 
 
<dl id="expMenu">  
    <dt id="all">  
        <asp:LinkButton ID="contentViewButton" Text="<%$Resources:ProductItems %>" runat="server" /> 
    </dt> 
    <dd> 
        <asp:Literal runat="server" Text="<%$Resources:ControlDescription %>"></asp:Literal> 
    </dd> 
      
    <dt id="cat"><asp:LinkButton ID="categoriesView" Text='<%$Resources:Categories %>' runat="server" CausesValidation="false"></asp:LinkButton></dt>  
    <dd><asp:Literal ID="Literal1" runat="server" Text="<%$Resources:CategoriesDescription %>"></asp:Literal></dd>  
      
    <dt id="tags"><asp:LinkButton ID="tagsView" Text="<%$Resources:Tags %>" runat="server" CausesValidation="false"></asp:LinkButton></dt>  
    <dd><asp:Literal ID="Literal2" runat="server" Text="<%$Resources:TagsDescription %>"></asp:Literal></dd>  
 
    <dt runat="server" id="commentsDt"><asp:LinkButton ID="commentsLink" Text="<%$Resources:Comments %>" runat="server" /></dt>  
    <dd runat="server" id="commentsDd"><asp:Literal runat="server" Text="<%$Resources:CommentsDescription %>"></asp:Literal></dd>  
 
    <!-- link is commented out because permissions are not used in SIMPLE IMPLEMENTATION --> 
    <!--  
            <dt id="globalPerm"><asp:LinkButton ID="permissionViewButton" Text="<%$Resources:Permissions %>" runat="server" /></dt>  
            <dd><asp:Literal ID="Literal3" runat="server" Text="<%$Resources:PermissionsDescription %>"></asp:Literal></dd>  
            --> 
</dl> 
 
After we’ve set the UI, it’s time to hook up some logic to the commentsLink OnClick event. Open following file which is located in the Telerik.Samples.Products project:

Telerik.Samples.Products.WebControls.Admin.CommandPanel

To make it easier to code against this new LinkButton, scroll down to the Container class and add a property which will allow us to access the reference to the LinkButton located in the template simply by referencing the property. Paste following code in the Container class:
public IButtonControl CommentsViewButton  
{  
   get 
   {  
      if (commentsViewButton == null)  
          commentsViewButton = (IButtonControl) FindRequiredControl<Control>("commentsLink");  
      return commentsViewButton;  
   }  
}  
IButtonControl commentsViewButton;  
 
Now, navigate to the CreateChildControls method of the CommandPanel class and add following code at the bottom of it, but before the Controls.Add(container) line:
// set up the behavior of CommentsViewButton  
container.CommentsViewButton.CommandName = "CommentsView";  
container.CommentsViewButton.Command += button_Command;  
if (container.CommentsViewButton is LinkButton && (ctrlPnl.Mode == Cms.Engine.WebControls.Admin.ControlPanel.Modes.CommentsView || ctrlPnl.Mode == Cms.Engine.WebControls.Admin.ControlPanel.Modes.CommentsEdit))  
   ((LinkButton)container.TagsViewButton).CssClass = "sel";  
 
This piece of code is simply assigning a command name and event handler to the commentsLink we’ve uncommented in the template and referenced through the container class. The last two lines of code are changing the css class of the link button to “sel” (as in “selected”) in case that control panel is in the CommentsView or CommentsEdit mode.

The last thing we need to do in CommandPanel class is add the logic which will handle the click on the commentsView linkbutton. Since, we’ve set button_Command as the event handler, scroll down to the button_Command method and add a case for CommandName being “CommentsView”. When you are done button_Command should look like this:
protected virtual void button_Command(object sender, CommandEventArgs e)  
{  
   // based on the command name, set the Mode of ControlPanel  
   ControlPanel ctrlPnl = ((ControlPanel) base.ControlPanel);  
   switch (e.CommandName)  
   {  
      case "ContentView":  
           ctrlPnl.Mode = Cms.Engine.WebControls.Admin.ControlPanel.Modes.List;  
           ctrlPnl.Refresh();  
           break;  
      case "CategoriesView":  
           ctrlPnl.Mode = Cms.Engine.WebControls.Admin.ControlPanel.Modes.Categories;  
           ctrlPnl.Refresh();  
           break;  
      case "TagsView":  
           ctrlPnl.Mode = Cms.Engine.WebControls.Admin.ControlPanel.Modes.Tags;  
           ctrlPnl.Refresh();  
           break;  
      case "CommentsView":  
           ctrlPnl.Mode = Cms.Engine.WebControls.Admin.ControlPanel.Modes.CommentsView;  
           ctrlPnl.Refresh();  
           break;  
   }  
 
   // loop through all the buttons, and make the button that sent the command  
   // have "sel" css class  
   foreach (Control ctrl in container.Controls[0].Controls)  
   {  
      if (ctrl is LinkButton)  
      {  
         LinkButton button = (LinkButton) ctrl;  
         button.CssClass = button.ID == ((LinkButton) sender).ID ? "sel" : "";  
      }  
   }  
}  
 

We are done with the CommandPanel class and you can save and close that file. The last thing on the admin side is to provide our products module with the admin side templates for comments related controls. Like so many times in this series, we’ll turn to the Generic_Content module and copy the templates located there. Copy following files:
~/Sitefinity/Admin/ControlTemplates/Generic_Content/CommentsEdit.ascx
~/Sitefinity/Admin/ControlTemplates/Generic_Content/CommentsList.ascx
~/Sitefinity/Admin/ControlTemplates/Generic_Content/CommentsView.ascx
~/Sitefinity/Admin/ControlTemplates/Generic_Content/App_LocalResources/CommentsEdit.ascx.resx
~/Sitefinity/Admin/ControlTemplates/Generic_Content/App_LocalResources/CommentsList.ascx.resx
~/Sitefinity/Admin/ControlTemplates/Generic_Content/App_LocalResources/CommentsView.ascx

to following folders respectively:

~/Sitefinity/Admin/ControlTemplates/Products
~/Sitefinity/Admin/ControlTemplates/Products
~/Sitefinity/Admin/ControlTemplates/Products
~/Sitefinity/Admin/ControlTemplates/Products/App_LocalResources
~/Sitefinity/Admin/ControlTemplates/Products/App_LocalResources
~/Sitefinity/Admin/ControlTemplates/Products/App_LocalResources

And we’re done with the admin side! Though it takes some “paper” to explain it, actually the process itself takes no more than 5 minutes.

Public side – adding the CommentsList control to the the details template

So, we’ve got everything working on the back side, now all we are left with is to add the UI for the visitors to leave and read the comments. Once again, there is a handy control which we are going to steal from the Generic Content module – the name of the control is CommentsList. Let’s start by copying the template for this control from the public templates of the Generic_Content modules to the public templates of our Products module. Copy following files:

~/Sitefinity/ControlTemplates/Generic_Content/CommentsList.ascx
~/Sitefinity/ControlTemplates/Generic_Content/App_LocalResources/CommentsList.ascx.resx

to following folders respectively:

~/Sitefinity/ControlTemplates/Products/
~/Sitefinity/ControlTemplates/Products/App_LocalResources

Now that templates are ready, open following file used to display single product:

~/Sitefinity/ControlTemplates/Products/ContentViewSingleItem.ascx

and add the CommentsList control somewhere in it, by pasting the following lines:

<sfWeb:CommentsList ID="commentsList" runat="server" TemplateUrl="~/Sitefinity/ControlTemplates/Products/CommentsList.ascx">  
</sfWeb:CommentsList> 
 

As you can see we have hardcoded the TemplateUrl, but we could also declare it inline, like it is done in Generic_Content or Blog folders (take a look at the detail templates of these modules).


Figure 2: ProductsView control with the CommentsList control – comments enabled on the public side of the module

And, believe it or not, this marks the end of our task - we’ve enabled our users with ability to comment on our products.

You can download the sample code for this project from here.

Leave a comment