
I found some few articles regarding this funtionallity in BlogEngine.NET but I'd really like to make my own. So as you can see from that screen shot, I have the widget on the left and sql query from the right. I used SQL Server anyway so if you guys still use XML, this is not for your BE. Well you can still read though to get some ideas.
Am using BE 1.6.1 - this could be compatible with 1.6 or lower version or higher? correct me if I'm wrong.
How things works?
Well I added a new table called "be_PostViews" and 2 new Stored Procedure to Update/Insert records and get the TOP 5 most viewed posts. Then I have a new Widget called "MostViewed".
Installation
Here are the SQLs you need for the table and stored procedure
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[be_PostViews](
[PostID] [nvarchar](50) COLLATE Latin1_General_CI_AS NOT NULL,
[TotalViews] [int] NOT NULL,
[DateUpdated] [datetime] NULL,
[DateCreated] [datetime] NULL,
[REMOTE_ADDR] [nvarchar](50) COLLATE Latin1_General_CI_AS NULL,
[HTTP_USER_AGENT] [nvarchar](255) COLLATE Latin1_General_CI_AS NULL,
[BROWSER_NAME] [nvarchar](50) COLLATE Latin1_General_CI_AS NULL,
[IS_CRAWLER] [nvarchar](50) COLLATE Latin1_General_CI_AS NULL
) ON [PRIMARY]
-- =============================================
-- Author: usp_get_most_viewed
-- Create date:
-- Description:
-- =============================================
CREATE PROCEDURE [dbo].[usp_get_most_viewed]
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
SELECT TOP 5
be_Posts.PostID,
be_Posts.Title,
be_PostViews.TotalViews,
be_PostViews.DateUpdated,
be_PostViews.DateCreated,
be_PostViews.*
FROM
be_Posts INNER JOIN
be_PostViews ON be_Posts.PostID = be_PostViews.PostID
ORDER BY be_PostViews.TotalViews DESC
END
-- =============================================
-- Author: usp_update_postview
-- Create date:
-- Description:
-- =============================================
CREATE PROCEDURE [dbo].[usp_update_postview]
-- Add the parameters for the stored procedure here
@thisPostID nvarchar(50),
@thisREMOTE_ADDR nvarchar(50),
@thisHTTP_USER_AGENT nvarchar(255),
@thisBROWSER_NAME nvarchar(50),
@thisIS_CRAWLER nvarchar(50)
AS
BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
-- Insert statements for procedure here
IF(EXISTS(SELECT PostID from be_PostViews WHERE PostID = @thisPostID))
BEGIN
DECLARE @thisTotalViews int;
SET @thisTotalViews = (SELECT TotalViews from be_PostViews WHERE PostID = @thisPostID)
SET @thisTotalViews = @thisTotalViews + 1;
UPDATE be_PostViews SET
TotalViews = @thisTotalViews,
DateUpdated=GETDATE(),
REMOTE_ADDR=@thisREMOTE_ADDR,
HTTP_USER_AGENT=@thisHTTP_USER_AGENT,
BROWSER_NAME=@thisBROWSER_NAME,
IS_CRAWLER=@thisIS_CRAWLER
WHERE PostID=@thisPostID;
END
ELSE
BEGIN
INSERT INTO be_PostViews(
PostID,
TotalViews,
DateCreated,
DateUpdated,
REMOTE_ADDR,
HTTP_USER_AGENT,
BROWSER_NAME,
IS_CRAWLER
)
VALUES(
@thisPostID,
1, GETDATE(), GETDATE(),
@thisREMOTE_ADDR,
@thisHTTP_USER_AGENT,
@thisBROWSER_NAME,
@thisIS_CRAWLER
);
END
SELECT TotalViews from be_PostViews WHERE PostID = @thisPostID
END
And for the Widget. It's basically just a control binding. Code is very basic. You do not really need extensive codes for this kind of feature. I'll just show you what's inside. You can just download it later.
This is the .ascx code which has 2 SqlDataSource. 1 for binding to Repeater control, and the other is for Inserting/Updating record in be_PostViews
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:BlogEngine %>"
SelectCommand="usp_get_most_viewed" SelectCommandType="StoredProcedure">
</asp:SqlDataSource>
<asp:Repeater ID="Repeater1" runat="server">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li><span><a href="post.aspx?id=<%# Eval("PostID") %>"><%# Eval("Title") %></a><br/><i><%# Eval("DateUpdated") %></i></span></li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
<asp:SqlDataSource ID="SqlDataSource2" runat="server"
ConnectionString="<%$ ConnectionStrings:BlogEngine %>"
SelectCommand="usp_update_postview" SelectCommandType="StoredProcedure">
</asp:SqlDataSource
This is the Code Behind for that widget. You don't have to touch any codes or pages in BlogEngine.NET, everything is done is this widget.
protected override void OnPreRender(EventArgs e)
{
Repeater1.DataSource = SqlDataSource1;
Repeater1.DataBind();
base.OnPreRender(e);
}
protected void Page_Load(object sender, EventArgs e)
{
object id = Request.QueryString["id"];
if (id != null)
{
pid = id.ToString();
System.Diagnostics.Debug.WriteLine("widget: " + id.ToString());
string ipaddress = string.Empty;
string browseragent = string.Empty;
string browsername = string.Empty;
string iscrawler = string.Empty;
ipaddress = Request.ServerVariables["REMOTE_ADDR"];
browseragent = Request.ServerVariables["HTTP_USER_AGENT"];
browsername = Request.Browser.Browser;
iscrawler = Request.Browser.Crawler.ToString();
SqlDataSource2.SelectParameters.Add("thisPostID", System.Data.DbType.String, pid);
SqlDataSource2.SelectParameters.Add("thisREMOTE_ADDR", System.Data.DbType.String, ipaddress);
SqlDataSource2.SelectParameters.Add("thisHTTP_USER_AGENT", System.Data.DbType.String, browseragent);
SqlDataSource2.SelectParameters.Add("thisBROWSER_NAME", System.Data.DbType.String, browsername);
SqlDataSource2.SelectParameters.Add("thisIS_CRAWLER", System.Data.DbType.String, iscrawler);
System.Data.DataView dataview = (System.Data.DataView)SqlDataSource2.Select(DataSourceSelectArguments.Empty);
}
}
If you think you can enhace some of the codes then I'd like to hear about it.
Post your questions here: http://blogengine.codeplex.com/discussions/262756
Download the code here: Most Viewed Widget.7z (2.11 kb)