London Dev Meetup Rescheduled! Due to unavoidable reasons, the event has been moved to 21st May. Speakers remain the same—any changes will be communicated. Seats are limited—register here to secure your spot!

Björn Olsson
Oct 8, 2011
  7066
(4 votes)

Creating a global navigation item plug-in, with EPiServer “look and feel”

I needed to create a global navigation item for a plug-in in my current project, beside the Visitor Groups item.

GlobalNav

I also wanted my plug-in to have the same look and feel as the other plug-ins/tools in edit/admin-mode. And my third wish, was as always, to implement this with as little effort as possible. I ended up doing the following steps:

1. Create a new Web Form named MyPlugin.aspx in a folder named Plugins.

2. Add the following code to the Web Form. This code will resolve and set the path to the same MasterPage used by EPiServer CMS, which saves us a lot of time, since it already contains all the necessary style sheets and javascripts.

namespace EPiServer.Plugins
{
    public partial class MyPlugin : EPiServer.UI.SystemPageBase
    {
        protected override void OnPreInit(EventArgs e)
        {
            base.OnPreInit(e);

            this.MasterPageFile = EPiServer.UriSupport.ResolveUrlFromUIBySettings("MasterPages/Frameworks/Framework.Master");
        }
    }
}

3. Add the following html to the Web Form. We’re using the content placeholder “FullRegion” which is defined in the MasterPage. The ShellMenu control will render the global navigation, and the SelectionPath property must be the same as we will be configuring in the next step. The remaining markup is a sample heading and table with EPiServer CMS style sheets applied.

<%@ Page Language="C#" AutoEventWireup="false" CodeBehind="MyPlugin.aspx.cs" Inherits="EPiServer.Plugins.MyPlugin" %>
<%@ Register TagPrefix="EPiServerShell" Assembly="EPiServer.Shell" Namespace="EPiServer.Shell.Web.UI.WebControls" %>
<asp:Content ContentPlaceHolderID="FullRegion" runat="server">
    <div>
        <EPiServerShell:ShellMenu runat="server" SelectionPath="/global/cms/myplugin" />
    </div>

    <div class="epi-padding">
        
        <div class="epi-contentContainer epi-fullWidth">
            
            <div class="epi-contentArea">
                <h1 class="EP-prefix">My Plugin</h1>
                <p>This is my example plugin with EPiServer look and feel</p>
            </div>
            
            <div class="epi-formArea">
                <table class="epi-default">
                    <tbody>
                        <tr>
                            <th>Heading 1</th>
                            <th>Heading 2</th>
                        </tr>
                        <tr>
                            <td>Value 1</td>
                            <td>Value 2</td>
                        </tr>
                    </tbody>
                </table>
            </div>
            
        </div>
        
    </div>
</asp:Content>

4. Configuration, locate the episerver.shell section in web.config, and add the navigation node as follows. This will make the new menu item appear in the global navigation under the CMS tab. The menuPath set here, must be the same as in the previous step, as I said.

<episerver.shell>
  <navigation>
    <add menuItemType="Link" menuPath="/global/cms/myplugin"
      sortIndex="100"
      text="My plugin"
      url="/Plugins/MyPlugin.aspx" />
  </navigation>
  <publicModules rootPath="~/modules/" autoDiscovery="Minimal"/>
  <protectedModules rootPath="~/secure/UI/">
    <add name="Shell"/>
    <add name="CMS"/>
  </protectedModules>
</episerver.shell>

Compile and run your project, a new global menu item is now available, and looks very dandy indeed:

GlobalNavMyPlugin

5. Security, protect your plugin from unauthorized users by adding the following nodes to web.config

<location path="Plugins">
  <system.web>
    <authorization>
      <allow roles="WebEditors, WebAdmins, Administrators"/>
      <deny users="*"/>
    </authorization>
  </system.web>
</location>

And there you go!

There is also an existing blog post regarding this, which covers the very basics, and some alternative ways to register your custom menu item.

Happy coding!

Oct 08, 2011

Comments

tompipe
tompipe Oct 10, 2011 10:47 AM

Hi Björn,

Nice clear post.

An alternative to messing with the episerver.shell in web.config is to decorate a class with the MenuProvider attribute, and ensure that class inherits from IMenuProvider.

Within the GetMenuItems method, you can return a list of MenuItems to populate your menu. e.g

[MenuProvider]
public class MyMenuProvider
{
public IEnumerable GetMenuItems()
{
return new List
{
new SectionMenuItem("My Plugin Section", "/global/cms/myplugin"),
new UrlMenuItem("My Plugin Item", "/global/cms/myplugin/item", "/Plugins/MyPlugin.aspx")
};
}
}

The SectionMenuItem and UrlMenuItem have various options to configure permissions and styling etc.

The relevant documentation is in the EPiServer.Shell.Navigation namespace, http://sdk.episerver.com/episerverframework/6.2/html/N_EPiServer_Shell_Navigation.htm

Björn Olsson
Björn Olsson Oct 10, 2011 10:53 AM

Yes, this previous blog post covers that, as i mentioned: http://world.episerver.com/Blogs/Dung-Le/Dates/2010/2/Create-Global-Navigation-in-EPiServer-CMS-6-RC1/ :)

Please login to comment.
Latest blogs
Notes on Optimizely Self-Optimizing Block

While the free A/B Testing might be dead , the Self-Optimizing Block is still alive and kicking. Here's some notes for those debugging it.  ...

Jacob Pretorius | Apr 29, 2025

Optimizely Product Recommendation Troubleshooting

In today’s fast-paced digital landscape, personalization is everything . Customers expect relevant, tailored experiences whenever they interact wit...

Sanjay Kumar | Apr 28, 2025

Natural Language Q&A in Optimizely CMS Using Azure OpenAI and AI Search

In Part 2, we integrated Azure AI Search with Azure Personalizer to build a smarter, user-focused experience in Optimizely CMS. We used ServiceAPI ...

Naveed Ul-Haq | Apr 25, 2025 |

Identifying Spike Requests and Issues in Application Insights

Sometimes within the DXP we see specific Azure App Instances having request spikes causing performance degredation and we need to investigate. I fi...

Scott Reed | Apr 25, 2025

Optimizely Frontend Hosting Beta – Early Thoughts and Key Questions

Optimizely has opened the waitlist for its new Frontend Hosting capability. I’m part of the beta programme, but my invite isn’t due until May, whil...

Minesh Shah (Netcel) | Apr 23, 2025

Developer Meetup - London, 21st May 2025

The London Dev Meetup has been rescheduled for Wednesday, 21st May and will be Candyspace 's first Optimizely Developer Meetup, and the first one...

Gavin_M | Apr 22, 2025