Creating Plugin Menu Items in NopCommerce 3.3

When writing your own plugins in NopCommerce there will be times when you want to add settings pages to the main Admin Menu for your users.  Let’s take a look at how this works in NopCommerce 3.3.

This tutorial won’t cover creating plugins in general – for a great ramp up you can visit the guide on the NopCommerce site here.

In order to add nav items you need to implement the IAdminMenuPlugin interface in your plugin’s main class – the one that inherits from BasePlugin or one of the other plugin parent classes.  IAdminMenuPlugin requires that we implement two methods – Authenticate() and BuildMenuItem().

Orchard 1.8 released!

Hey people,

Orchard 1.7.3 and 1.8 were released today…awesome! Sounds like it comes with a number of great improvements.  You can see the official release here.

Orchard 1.7.3 mostly just handles bug fixes, where as 1.8 adds some great enhancements and features.  I’ll try to cover some of these more in depth in future blog posts.  The highlights are listed below:

  • Supposedly a huge performance improvement by switching to an infoset structure for the database – content items are now stored as one XML entry in the database rather than every content part being stored in a separate table
  • Upgraded to ASP.NET 4.5 and MVC 5.1 with Razor 3.1
  • The once deprecated List Module is back and looks pretty awesome now. It basically lets you pick and choose random content items to add to a list that can be displayed as a page or widget. It also allows for sorting and can be restricted to certain content types, etc.  Kind of like a lightweight projector module if you’re familiar with that, though it’s designed to mirror the basic blog functionality.  This functionality kind of reminds me of a SharePoint List, though this is purely my opinion and is not meant to imply an technical similarities.
  • Job Queue Module – Not exactly sure how thie works, I’ll have to dig into it.  Seems like an improved way for queuing up tasks like sending emails or other workflow type setups.
  • Lots of bug fixes from 1.7.2 (I think the custom forms bug has been fixed)
  • Improved Caching
  • Azure improvements such as full Azure Media Services integration – from my understanding this means you can replace the media library with an Azure repository and also stream video through Azure
  • Media library enhancements (folders can now be collapsed!

Download it today and check it out!

Creating Content Fields Programmatically in Orchard

One of the most compelling features of Orchard is its strong support for building and managing Content Types right out of the box through the Admin UI.  However, there will almost certainly be times when you want to create Content Types programmatically.  Maybe you are looking to package the Content Types into a reusable plugin, or maybe you just want more control and structure over what gets built on your site.  Whatever the reason, building Content Types programmatically is actually pretty easy.

The Content Type system in Orchard is an expansive topic, so we will be focusing on only one aspect of it in this post.  Specifically, we are going to look at how to add the built in Content Fields to Content Types programmatically. This topic isn’t all that complicated, but the syntax can be confusing and documentation is a bit sparse if you’re looking for info on every Field type.  I am going to show code examples for a few types of field you can add to a Content Type, and then I will show you how to figure out the syntax for all the other types on your own.

Another small note: You can also create Content Fields and Content Parts in Orchard that are backed by strongly typed classes and database entries you define using custom schemas.  These types of Content Fields and Content Parts are useful if you want to add in some kind of custom logic when items are saved or retrieved, among other benefits.  However, in a lot of cases you just want to save and display the information directly entered by the user.  In these situations you simply need to tell Orchard what types of fields you want (what we are doing in this post) and it will handle the rest for you.  If none of that makes sense to you yet, don’t worry about it – you will know when you encounter a situation that requires Content Fields backed by logic.

Anyway, onto the task at hand!

Installing Orchard On Azure with a Custom Domain name

One of the great characteristics of Orchard is the ease at which you can get a site up and running, especially for development purposes. However, this process can be a bit of a headache with hosting providers that are not optimized for the type of environment Orchard demands – an IIS web server with a site running in full trust mode. Yes, you can technically run Orchard in medium trust, but you lose some optimizations. If you’re going to host Orchard on a third party provider, you want to make sure you’re getting the best environment possible. I have found Microsoft’s Azure to be a great choice for Orchard, partially due to its ability to install applications for you through its web application gallery.

To get started you’ll obviously need an Azure account, or at least sign up for a free trial. After you’re registered, head over to your dashboard and click on “Websites”. If you are just starting out with Azure, no websites will be listed, so click the “+ New” button in the bottom left corner. Choose “From Gallery” on the menu that pops up to open the Apps for Azure dialog.

Cross Site Collection Navigation in SharePoint Using the Term Store

Navigation within SharePoint can often cause confusion and frustration among users and admins.  Whether it’s users not understanding where they are, or Admins not knowing how to structure things in a sensible way, Navigation can be challenging. Today we are going to take a look at a fairly common (and frustrating) scenario – cross site collection navigation.   By default SharePoint 2010 and 2013 do not allow for cross site collection navigation, meaning the same navigation set or structure isn’t available to an entire web application.  One site collection cannot easily link to items in another without using custom, hard coded links.

There were hopes that SharePoint 2013 would address this issue, but it has not – not really, anyway.  It’s true that managed navigation is improved in SharePoint 2013 – meaning you can use the term store to build a navigation set that can be displayed on your site collections.  However, a term set can only be attached to one site collection at a time, so in essence this is still limited to one Site Collection.  Yes, there are ways of stapling a duplicate term set to the master term set, but this copying process is very error prone and does not update child sets properly in all scenarios.  Some people live with this implementation but I feel it’s a huge mess.  I wanted to figure out something more manageable.

It turns out that accessing the term store through the SharePoint object model eliminates a lot of the weird limitations imposed through the UI.  For example, we can access a term set from the root site collection of a web application and surface the data inside of a user control that can be injected across ALL site collections using a custom Master Page.  Let’s explore how this all works together using a custom solution in Visual Studio.

Create a new Empty SharePoint 2010 or 2013 project in Visual Studio called GlobalNav and choose to deploy it as a farm solution.  This scenario will not work in SharePoint Online or environments that require Sandbox solutions, since these do not allow User Controls.  I am also connecting to a Publishing Site since that will allow us to easily assign our custom Master Page, though you could also use a Team Site with a  few extra steps.  The code shown will be running in 2013 but should work in 2010 as well.

After your solution is built, right click the project and add a User Control.  You can call it “GlobalNav” if you want all of the code samples included here to work, or you can go rogue with your own naming and just borrow the concepts.  Visual Studio will automatically create the ControlTemplates directory for SharePoint and add your User Control.

solution

Open GlobalNav.ascx and add the following line of code below all of the text Visual Studio generates for you:

<asp:Label ID="GlobalNavContainer" runat="server" ViewStateMode="Disabled" CssClass="GlobalNavContainer"></asp:Label>

This is all of the content that will be added to GlobalNav.ascx – it’s nothing more than a standard Label Control.  Our code behind file will build and inject the nav HTML into this container.

Next open up GlobalNav.ascx.cs – this is where all of our logic to access the term store will be added.  Copy and paste code below inside your class.  You may need to add a project reference to Microsoft.SharePoint.Taxonomy.   Let’s take a moment to walk through this code.

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Taxonomy;
 
namespace GlobalNav.ControlTemplates.GlobalNav
{
    public partial class GlobalNav : UserControl
    {
        public static string html { getset; }
 
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    using (SPSite thisSite = new SPSite(SPContext.Current.Site.WebApplication.AlternateUrls[0].Uri.AbsoluteUri))
                    {
                        html = "";
                        TaxonomySession session = new TaxonomySession(thisSite);
                        TermStoreCollection store = session.TermStores;
 
                        try
                        {
                            foreach (TermStore termStore in session.TermStores)
                            {
                                Group navGroup = termStore.Groups["Navigation"];
                                foreach (TermSet topSet in navGroup.TermSets)
                                {
                                    html += writeTerms(topSet.Terms);
                                }
                            }
                        }
                        catch
                        {
                        }
 
                        finally
                        {
                            GlobalNavContainer.Text = "";
                            GlobalNavContainer.Text = html;
                        }
                    }
                });
            }
        }
 
        public string writeTerms(TermCollection terms)
        {
            if (terms.Count > 0)
            {
                html += "\n<ul class=\"GlobalNav\">\n";
                foreach (Term subTerm in terms)
                {
                    try
                    {
                        html += "<li><a href=\"" + subTerm.LocalCustomProperties["_Sys_Nav_SimpleLinkUrl"] + "\">" + subTerm.Name + "</a>";
                        writeTerms(subTerm.Terms);
                        html += "</li>\n";
                    }
 
                    catch
                    {
                        html += "<li><a href=\"#\">" + subTerm.Name + "</a>";
                        writeTerms(subTerm.Terms);
                        html += "</li>\n";
                    }
                }
 
                html += "</ul>\n";
            }
            return html;
        }
    }
}

First we get a reference to the root site collection inside of our using statement – the url of our web application is the same as the root site collection.  Next we make sure the variable that will store our html is set to empty.  We want to gain access to our Term Stores – particularly the top level group which we will call Navigation.  I wasn’t sure of the best way to make this not hard coded, so for demo purposes just make sure you have a group called Navigation or whatever you want as your top level item.  Basically all we have to do now is loop through every term set in the navigation group and call our writeTerms method.

WriteTerms is a special recursive function that generates the HTML that will be injected into our user control.  The recursive aspect is important because it means our navigation will support unlimited levels of navigation by continually traversing down the hierarchy of each term set until it cannot find another child.  Obviously you will need appropriate CSS/Javascript to support multiple levels of navigation, but the HTML output is very simple and clean.  Generally I try to avoid string building HTML, but here it’s only a few elements.  There are a couple other details here – the try catch is so that if they leave out the link field it won’t cause an error when SharePoint tries to access it.  I am not a fan of using Try Catch blocks in production code but I’m not sure of a way to avoid it here.  You could also abstract the Try Catch into a wrapper method for cleaner looking code.

Next you need to add this user control to your Master Page.  You can just use a starter master page from codeplex for this example, or your own.  This tutorial assumes you have a general idea of how to deploy a custom Master Page, but here is a short refresher:  Right click your project and choose Add New Item.  Select an item of Module to add to your project – Modules are used to deploy files to SharePoint.  Paste your starter Master Page File into this module and make sure your Elements.XML in the module looks something like this:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <Module Name="MasterPage" Url="_catalogs/masterpage">
    <File Path="MasterPage\Starter.master" Url="Starter.master" Type="GhostableInLibrary" />
  </Module>
</Elements>

The Module URL determines where the files will deployed – in this case we want them to go to the Master Page Gallery.  Remember, File Path is the path to the file within your solution, URL is the path to the file after it’s deployed, relative to the module URL.

Open up your new Master Page and add a new Register tag at the top of the Master Page beneath the others – it should look something like this:

<%@Register TagPrefix="GlobalNav"  TagName="GlobalNav" Src="~/_controltemplates/GlobalNav/GlobalNav.ascx" %>

We can now add the actual User Control onto the Master Page. You can technically put this almost anywhere. I had to play around with it a bit to get it exactly where I wanted in the HTML, but I ended up adding it just above where the search Control starts (if you’re using the start master pages).

<GlobalNav:GlobalNav id="GlobalNav" EnableViewState="false" runat="server" />

Lastly we need to add some CSS.  For demo purposes you can just add a <style> element to GlobalNav.ascx and paste the CSS below inside of it.  If you are deploying this production at some point you should abstract this into its own CSS file and include it on the master page.  Inline CSS is bad.  This styling might not render perfectly for you depending on how your test environment it set up but hopefully it’s a good starting point.  You can also exclude this CSS entirely to see the raw html output rendered in the browser.

.GlobalNav
{
    margin0;
    padding0;
    list-stylenone;
}
 
.GlobalNav li
{
    floatleft;
    padding10px;
}
 
.GlobalNav ul
{
    displaynone;
    background#FCFCFC;
    border1px solid #eee;
    box-shadow1px 1px 7px #ccc;
    z-index10000;
}
 
.GlobalNav ul li
{
    positionrelative;
    displayblock;
    width100%;
}
 
.GlobalNav ul li:hover
{
    background#eee;
}
 
.GlobalNav > ul
{
    displayblock;
}
 
.GlobalNav > ul li
{
    displayblock;
    floatleft;
}
 
.GlobalNav > li:hover > ul
{
    displayblock;
    positionabsolute;
    width200px;
}
 
.GlobalNav > li ul li:hover > ul
{
    displayblock;
    positionabsolute;
    width200px;
    right-200px;
    top0;
}

Next we need to configure our Term Store.  First head over to Central Admin and make sure you have a Managed Meta Data Service Running with the right permissions.  I gave all authenticated users Read Permission on the service so that everyone could at least see the nav.

permissions

After you have this configured, click on the Meta Data Service text to actually navigate to the term store.  Here you can assign administrators who will be allowed to edit the actual terms.   The most important thing here is to actually build out your navigation – make sure your top level group matches the name you used in your code, which is “Navigation” in my case.  I then added  a top level term set that will contain all of our nav items, called “Master Nav”.

termstore

At this point if you build and run your solution you should have a semi-working global nav.  You may have to go into your site settings and assign the new master page as your custom master – you could also write code to apply this automatically on feature activation, but we won’t cover that here.  My results ended up something like the image below.  It’s not beautiful yet, but it’s very functional and includes unlimited levels of drop downs via hover.   And, of course, it works across site collections!  Start building out your styling and your term store to see how far you can take this concept.

drop-down

Creating a Publishing Field Declaratively and Programmatically in SharePoint

I recently came across a task in SharePoint that nearly drove me insane. I was creating a publishing layout template and I needed to add some “Publishing HTML” fields so the user would have full editing control inside that editable field. Doing this declaratively using a SharePoint feature in Visual Studio is simple enough – some example code is below:

<?xml version="1.0" encoding="utf-8"?>
  <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
    <Field ID="{your-guid-here}" Type="HTML" RichText="TRUE" RichTextMode="FullHTML" Name="YourInternalName" DisplayName="Your Display Name" Group="YourGroupName"></Field>
  </Elements>

Be sure to use the type “HTML”. This type is not included on many of the lists that describe all of the types in SharePoint, because a lot of those only cover SharePoint foundation and this is part of the Publishing Infrastructure of SharePoint Server. Remember, you can generate your own guids inside of Visual Studio under “Tools”. Also, remember to not include spaces in your internal name for cleanliness (spaces get converted to %20 behind the scenes).

The harder part is how to create this programmmatically. I haven’t tried this in SharePoint 2013, but 2010 seems to have a bug that does not let you instantiate the HTMLField class correctly, which limits your ability to use the straight server object model. Every time I attempted this I received the dreaded “column failed to install correctly error. Avoid this.

Instead, try creating the column programmatically using the AddFieldAsXML method of the SPFieldsCollection class, and then passing in the declarative XML that we know works. Make sure to escape your quotes, as seen below.

Streaming Authenticated Video with Amazon Web Services and .NET

Welcome! This post is designed to alleviate much of the confusion surrounding AWS video streaming, specifically with .NET applications. If you are looking for a complete guide to setting up authenticated streaming for both HTML 5 and Flash from start to finish, this is the place to be. If you are already familiar with AWS, hopefully there will be a few helpful tips along the way.

Note: AWS does feature some fairly helpful tutorials on their own site for setting up basic, public video streaming. However, setting up fully authenticated video with .NET is another story, and a lot of the information out there is fragmented and confusing.

This tutorial is available as both a video and as a written tutorial.

Download PDF version by clicking here.

The contents of the PDF are broken down by section, whereas the video is one segment. The two are almost identical in content, though they may not be organized quite the same. Here are the approximate time marks for each section of the video if you are interested in jumping around:

Setting up a solution for testing: 00:00

Creating the buckets and uploading our resources: 3:00

Adding Distributions and an Origin Access Identity: 6:08

Generating a properly formatted private key and policy for signed urls: 10:50

Generating Signed URLs: 20:05

Adding flash fallback and alternate video formats: 27:53

Check out the full video below:

Adding an RSS Feed to Sharepoint Using a Web Part

Note: This tutorial assumes at least basic knowledge of creating and deploying SharePoint Solutions using Visual Studio

A common request I have seen crop up a number of times when working with SharePoint is to add an RSS feed to the site. There are a handful of SharePoint Apps out there on the SharePoint store that will do this for you, but I wanted to take a look at coding this myself and packaging it as a custom web part. After doing a little digging this turned out to be fairly straight forward. RSS feeds are obviously pretty easy to work with, so it was really just a matter of finding the most efficient methods.

Some of you may be familiar with the System.ServiceModel.Syndication Namespace that is part of the .NET library. This namespace contains some really useful classes designed to work with RSS feeds. For this example, we are going to take a look at the SyndicationFeed and SyndicationFeedItem classes with this namespace.