Allan Thraen
Jul 4, 2011
(2 votes)

Summer of Code: Update to the Mapped Page Provider

A lesson I’ve learned the hard way is that being product manager for a product like EPiServer CMS with thousands of dedicated developers and editors, your life tend to get rather busy. At least mine does. Dozens of meetings, presentations, customer interviews,  conferences, requirement docs and an obscene amount of travel days. And although it can be both rewarding and fun it’s not always as glamorous as it sounds Smile. This means that it’s been difficult to do all my usual “fun stuff” like coding open source projects and blogging about it – and I’ve sadly had to watch my status on the “Top Bloggers” board on EPiServer World go down. Obviously, I can’t have that – so in the hope that July means “Swedes are out of the office on strangely long vacations and I won’t be all that busy product manager’ing” I’ll now declare it the “Summer of Code” and start pushing out a series of blog posts with a lot of small goodies that I’ve had in mind for a long time. If you like me find yourself with a little time on your hand this July, bring your laptop out into the sun, fire up Visual Studio and join the Summer of Code. I’ll buy a cold beer to anyone who launches a cool, useful – and easily installable – module for EPiServer CMS this July. Don’t make me drink all the beers myself.

Todays’ effort included upgrading the Mapped Page Provider project to take advantage of the Dynamic Data Store – and wrap it in a nice little NuGet Package.
As you might recall, the Mapped Page Provider is a new base class to use when creating custom page providers, that makes it a lot easier to expose an existing data source as pages in the CMS. With the Mapped provider you don’t need to deal with all the nitty-gritty of Guids, ID’s, Urls, etc yourself – but rather just connect string-keys with home-brewed page-data objects.

A little while ago I was playing around trying to make a little source-code-browser (which might eventually be available if I manage to get the right political buy-in for it) and it seemed natural to expose the source-code copied to a VPP through a PageProvider in order to get nice looking urls – and easy navigation through the source. Using the Mapped Provider it didn’t take long to turn a VPP with source files into a PageTree in the CMS:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using EPiServer.Core;
using EPiServer.Research.PageProviders;
using EPiServer.Web.Hosting;
using System.Web.Hosting;
using System.IO;
namespace SourceCodeBrowser.PageProvider
    //A read-only page provider for source code - Browse either by file or by classes
    public class CodePageProvider : MappedPageProvider
        protected static string rootpath = "/SourceCodeBrowser/Source/";
        protected static string[] allowedext = {".cs",".aspx",".ascx",".config",".js",".css" };
        protected override List<string> GetRootChildren()
            //List Vpp root folder
            return GetChildren(rootpath);
        protected override List<string> GetChildren(string Key)
            //List children under a given VPP root
            //Leaf or not
            if (Key.EndsWith("/"))
                var dir=VirtualPathHandler.Instance.GetDirectory(Key, true);
                var rt = dir.Directories.Cast<VirtualFileBase>().Select(vfb => vfb.VirtualPath).ToList();
                    .Where(vfb => allowedext.Contains(
                        VirtualPathUtility.GetExtension(vfb.VirtualPath.ToLower()))).Select(vfb => vfb.VirtualPath).ToList());
                return rt;
            else return new List<string>();
        protected override PageData GetPage(string Key)
            PageData pd = new PageData();
            //Identify parent
            string parent = null;
            if(Key!=rootpath)  parent=VirtualPathUtility.GetDirectory(Key.TrimEnd('/'));
            if (parent == rootpath) parent = null;
            string nm=VirtualPathUtility.GetFileName(Key);
            InitializePageData(pd, Key, nm ?? Key, parent);
            if (Key.EndsWith("/"))
                //Load file contents into property
                var f=VirtualPathHandler.Instance.GetFile(Key, true) as NativeFile;
                StreamReader read = new StreamReader(f.Open(System.IO.FileMode.Open, System.IO.FileAccess.Read));
                pd.SetValue("Code", read.ReadToEnd().Replace("<","&lt;").Replace(">","&gt;"));
                pd.SetValue("CodeType", VirtualPathUtility.GetExtension(Key).TrimStart('.'));
                pd.SetValue("PageStartPublish", f.Changed);
            return pd;
        protected override string GetPageType(string Key)
            return (Key.EndsWith("/")) ? "FolderPageType" : "CodePageType";


Summer of code

Other things lined up for this month (if time permits):

  • New NuGet version of the QuickWatchGadget (with dynamic code-execution)
  • A bunch of new Criteria for the CriteriaPack – including an XForms Criterion
  • Update to the MobilePack – maybe it’s time for v.1.0
  • Sharing some of the code I demoed at the US Partner Summit – like the Twitter Integration
  • A few new gadgets might also find their way to this blog
  • And a bunch of ‘secret’ stuff that I don’t want to share just yet Smile


Happy summer everybody!

Jul 04, 2011


Fredrik Josefsson
Fredrik Josefsson Jul 5, 2011 10:02 AM

Looking forward to your new blog posts :)

Please login to comment.
Latest blogs
Preview multiple Visitor Groups directly while browsing your Optimizely site

Visitor groups are great - it's an easy way to add personalization towards market segments to your site. But it does come with it's own set of...

Allan Thraen | Sep 26, 2022 | Syndicated blog

The Report Center is finally back in Optimizely CMS 12

With Episerver.CMS.UI 12.12.0 the Report Center is finally re-introduced in the core product.

Tomas Hensrud Gulla | Sep 26, 2022 | Syndicated blog

Dynamic Route in ASP.NET Core When MapDynamicControllerRoute Does Not Work

Background Creating one of the add-on for Optimizely I had to deal with challenge to register dynamically route for the API controller. Dynamic rou...

valdis | Sep 25, 2022 | Syndicated blog

404 Error on Static Assets Within an Optimizely plugin

Background With the move to CMS 12 and .NET 5/6, developers are now able to build Plugins and Extensions using Razor Class Libraries (RCL).  These...

Mark Stott | Sep 23, 2022

How to bypass the content creation view in Optimizely

Something that has come up a couple of times in the last few year is feedback from content editors about the editing view that comes up when creati...

Ynze | Sep 23, 2022 | Syndicated blog

Welcome to Optimizely World's New Tech Video Portal

Optimizely, leader in the digital experience realm, has become a wealth of world class SaaS products including Web Experimentation, Full Stack, B2B...

The Developer Marketing Team of Optimizely | Sep 22, 2022