Visual Studio Achievements Widget for BlogEngine

If you code in Visual Studio, you've probably heard of Channel 9's Visual Studio plugin that allows developers to earn achievements based on certain criteria met while programming in a visual studio solution.The Visual Studio Achievements plug-in analyzes a background thread each time code is compiled, as well as listens for particular events and actions from Visual Studio. The plugin has a leaderboard on Channel 9's website and there is also a REST API available to query user achievements. I decided to mess around with the API and develop a widget for BlogEngine.net. Now I know there is already a widget that you can easily insert into your theme that does essentially the same thing I created but you don't have the ability to change the data output or design of their widget. I made this pretty quickly and it does need some work. I appreciate any feedback or contributions to the widget.

Visual Studio Achievements Widget for BlogEngine.net
Visual Studio Achievements Widget for BlogEngine.net

 

Download it here: http://dnbegallery.org/cms/List/Widgets/VS-Achievements

JQ Mobile Theme for Blogengine.net

I created a mobile theme for Blogengine.net that uses JQuery Mobile. JQ Mobile overrides a lot of the default html and pages that normal Blogengine themes use and turns a Blogengine.net site into a mobile app.

JQ Mobile - Screenshot1
Home page - List of recent posts with paging

JQ Mobile - Screenshot2
Archive page - Grouped by Category and quick filter search on all posts

JQ Mobile - Screenshot3
Contact page

JQ Mobile - Screenshot4
Search page

 

Download JQ Mobile: here.

BlogEngine.net Featured Posts Rotator Extension using JQuery

I had this need to showcase featured posts on the front page of my blog with a large image. I did not see any extensions for BlogEngine.net that did this, so I decided to write my own. This extension uses JQuery and a JQuery plugin called InnerFade.

Featured Posts Rotator BlogEngine.net Extension
Featured Posts Rotator Extension used by mobiletvworld.com

Admin
The Extension settings are pretty basic. You select if you want to add a CDN reference of the JQuery Framework to the header of your webpages or leave unchecked if you already reference JQuery in you theme. Next, you select a post you want to add an image to and hit upload.

Featured Posts Rotator Extension Admin Screen
Featured Posts Rotator Admin Screen

Theme SiteMaster
In your themes SiteMaster, add the following code in order for the rotator to appear on you blog. Note that if you do not add any images in the admin, the rotator control will not render to the front page.

style.css
Edit the style.css that is located in User controls/FeaturedPostsRotator/style.css to fit the needs of you theme.

The 1.0 version was written very quickly and may contain bugs so please report any. This extension has very basic features but I see the possibilities of adding more features to control settings in the admin in the future! Enjoy!

FeaturedPostsRotator_1.0.zip (14.59 kb)

BlogEngine.net Custom Widget Properties

For the theme on my site, I wanted to add individual styles to certain widgets to differentiate them from one and another and break up the monotonous look. In order to do that, I added a property to the Widget called CSSClass that appends a name to the existing class: widget so you can add different styles in your css to change the look of certain widgets.

 

BlogEngine.net Custom Widget Styles

Back to Top

Custom BlogEngine Widgets

So instead of class="widget", you could have class="widget_green" or class="widget_red"

 

App_GlobalResources/

Add name: cssClass value: CSS Class

App_Code/Controls/

WidgetBase.cs

WidgetBase.cs - Top of class
//Add this to properties at top of WidgetBase.cs
private string _CSSClass;
/// 
/// Gets or sets the style of the widget. It is mandatory for all widgets to set the Style.
/// 
/// The style of the widget.
public string CSSClass
{
get { return _CSSClass; }
set { _CSSClass = value; }
}
//Added CssClass to widget class attribute to "protected override void Render(HtmlTextWriter writer)" and some custom title class and bottom class for my postit note widget styles
protected override void Render(HtmlTextWriter writer)
{
if (string.IsNullOrEmpty(Name))
throw new NullReferenceException("Name must be set on a widget");
StringBuilder sb = new StringBuilder();
sb.Append("
"); if (Thread.CurrentPrincipal.IsInRole(BlogSettings.Instance.AdministratorRole)) { sb.Append("X"); if (IsEditable) sb.Append("" + Resources.labels.edit + ""); } if (ShowTitle) { sb.Append("

" + Title + "

"); } else { sb.Append(" "); } sb.Append("
"); writer.Write(sb.ToString()); base.Render(writer); writer.Write("
"); writer.Write(""); writer.Write("
"); }

WidgetEditBase.cs

WidgetEditBase.cs - Properties
//Add to WidgetEditBase.cs Properties
private string _CSSClass;
/// 
/// Gets or sets the CSS class of the widget. It is mandatory for all widgets to set the CSS Class.
/// 
/// The CSS class of the widget.
public string CSSClass
{
get { return _CSSClass; }
set { _CSSClass = value; }
}

WidgetZone.cs

WidgetZone.cs - OnLoad(EventArgs e)
//Add to WidgetZone.cs "protected override void OnLoad(EventArgs e)"
control.CSSClass = widget.Attributes["cssclass"].InnerText;

admin/

WidgetEditor.aspx

//Add to WidgetEditor.aspx below ""
<%=Resources.labels.cssClass %>   

WidgetEditor.cs

WidgetEditor.cs - btnSave_Click(object sender, EventArgs e)

//Add to WidgetEditor.cs in "private void btnSave_Click(object sender, EventArgs e)"
if (node.Attributes["cssclass"].InnerText != txtCSSClass.Text.Trim())
{
node.Attributes["cssclass"].InnerText = txtCSSClass.Text.Trim();
isChanged = true;
}
//Add to "private void SaveNewWidget(WidgetBase widget)"
XmlAttribute cssclass = doc.CreateAttribute("cssclass");
cssclass.InnerText = "";
node.Attributes.Append(cssclass);
//Change to "private void InitEditor(string type, string id)"
private void InitEditor(string type, string id)
{
XmlDocument doc = GetXmlDocument();
XmlNode node = doc.SelectSingleNode("//widget[@id=\"" + id + "\"]");
string fileName = Utils.RelativeWebRoot + "widgets/" + type + "/edit.ascx";
if (File.Exists(Server.MapPath(fileName)))
{
WidgetEditBase edit = (WidgetEditBase)LoadControl(fileName);
edit.WidgetID = new Guid(node.Attributes["id"].InnerText);
edit.Title = node.Attributes["title"].InnerText;
edit.ID = "widget";
edit.ShowTitle = bool.Parse(node.Attributes["showTitle"].InnerText);
edit.CSSClass = node.Attributes["cssclass"].InnerText;
phEdit.Controls.Add(edit);
}
if (!Page.IsPostBack)
{
cbShowTitle.Checked = bool.Parse(node.Attributes["showTitle"].InnerText);
txtTitle.Text = node.Attributes["title"].InnerText;
txtTitle.Focus();
txtCSSClass.Text = node.Attributes["cssclass"].InnerText;
btnSave.Text = Resources.labels.save;
}
btnSave.Click += new EventHandler(btnSave_Click);
}

blog.js

blog.js - function editWidget(name, id)

//Change to "function editWidget(name, id)" for additional 50px from 500 to 550 height because of extra Property
var size = { 'height': 550, 'width': 750 };

CSS Example

/***********************************************
** WIDGETS
***********************************************/
/*GLOBAL*/
.widget,
.widget_green,
.widget_red,
.widget_blue{
width: 240px;
margin-bottom: 20px;
padding: 0;
display: block;
}
.widget ul,
.widget_green ul,
.widget_red ul,
.widget_blue ul{
list-style: none;
padding: 0;
margin: 0;
}
.widget li,
.widget_green li,
.widget_red li,
.widget_blue li{
margin: 0 0 0 15px;
}
.widget .content,
.widget_green .content,
.widget_red .content,
.widget_blue .content{
padding: 15px 10px 15px 10px;
}
.widget-bottom,
.widget_green-bottom,
.widget_red-bottom,
.widget_blue-bottom{
width: 240px;
height: 5px;
}
.widget .edit,
.widget_green .edit,
.widget_red .edit,
.widget_blue .edit{
float: right;
margin: 0 5px 0 0;
}
.widget .delete,
.widget_green .delete,
.widget_red .delete,
.widget_blue .delete{
float: right;
}
/*YELLOW*/
.widget{background: url(css/images/grunged_widget_yellow.png) 0 top no-repeat scroll;}
.widget-bottom{background: url(css/images/grunged_widget_yellow.png) 0 bottom no-repeat scroll;}
/*GREEN*/
.widget_green{ background: url(css/images/grunged_widget_green.png) 0 top no-repeat scroll; }
.widget_green-bottom{background: url(css/images/grunged_widget_green.png) 0 bottom no-repeat scroll;}
/*RED*/
.widget_red{background: url(css/images/grunged_widget_red.png) 0 top no-repeat scroll;}
.widget_red-bottom{background: url(css/images/grunged_widget_red.png) 0 bottom no-repeat scroll;}
/*BLUE*/
.widget_blue{background: url(css/images/grunged_widget_blue.png) 0 top no-repeat scroll;}
.widget_blue-bottom{background: url(css/images/grunged_widget_blue.png) 0 bottom no-repeat scroll;}
/*TITLES*/
div.widget_title{
width: 180px;
height: 30px;
margin: 10px 0 0 5px;
padding: 0;
display: block;
}
div.widget_title h4{display: none;}
.administration .widget_title{background: url(css/images/grunged_widget_title.png) 0px 0px no-repeat scroll;}
.blogroll .widget_title{background: url(css/images/grunged_widget_title.png) 0px -30px no-repeat scroll;}
.calendar .widget_title{background: url(css/images/grunged_widget_title.png) 0px -60px no-repeat scroll;}
.categorylist .widget_title{background: url(css/images/grunged_widget_title.png) 0px -90px no-repeat scroll;}
.linklist .widget_title{background: url(css/images/grunged_widget_title.png) 0px -120px no-repeat scroll;}
.monthlist .widget_title{background: url(css/images/grunged_widget_title.png) 0px -150px no-repeat scroll;}
.mostcomments .widget_title{background: url(css/images/grunged_widget_title.png) 0px -180px no-repeat scroll;}
.newsletter .widget_title{background: url(css/images/grunged_widget_title.png) 0px -210px no-repeat scroll;}
.pagelist .widget_title{background: url(css/images/grunged_widget_title.png) 0px -240px no-repeat scroll;}
.recentcomments .widget_title{background: url(css/images/grunged_widget_title.png) 0px -270px no-repeat scroll;}
.recentposts .widget_title{background: url(css/images/grunged_widget_title.png) 0px -300px no-repeat scroll;}
.search .widget_title{background: url(css/images/grunged_widget_title.png) 0px -330px no-repeat scroll;}
.tagcloud .widget_title{background: url(css/images/grunged_widget_title.png) 0px -360px no-repeat scroll;}
.twitter .widget_title{background: url(css/images/grunged_widget_title.png) 0px -390px no-repeat scroll;}

MichaelJBaird.com and BlogEngine.net

Well I finally got my website up and running. After a couple of years using Joomla and a Apache/MySQL environment, I switched to ASP.NET, VistaDB Express, C# using the .NET open source application BlogEngine.net.

 

Back to Top

BlogEngine.net

As a developer, I was happy to learn that BlogEngine.net was completely open source so I could modify the code to suit my needs for my site. Also, it is very easy to either implement an existing blog theme or make your own, which is what I did with my site. I’ve looked at quite a lot of .Net blog software including some expensive paid versions and I have to say BlogEngine.Net is the best and easiest to set up that I have seen so far. If you are looking for a .NET based blog solution, I would highly recommend it.

I will be providing my experiences and knowledge with BlogEngine.net and as well with other things in the future.