Vulnerability in EPiServer.Forms

Try our conversational search powered by Generative AI!

Allan Thraen
Jul 4, 2011
  5469
(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();
                rt.AddRange(dir.Files.Cast<VirtualFileBase>()
                    .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("/"))
            {
                //Folder    
            }
            else
            {
                //File
                //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('.'));
                read.Close();
                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

Comments

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

Looking forward to your new blog posts :)

Please login to comment.
Latest blogs
Stop Managing Humans in Your CMS

Too many times, a content management system becomes a people management system. Meaning, an organization uses the CMS to manage all the information...

Deane Barker | Nov 30, 2023

A day in the life of an Optimizely Developer - Optimizely CMS 12: The advantages and considerations when exploring an upgrade

GRAHAM CARR - LEAD .NET DEVELOPER, 28 Nov 2023 In 2022, Optimizely released CMS 12 as part of its ongoing evolution of the platform to help provide...

Graham Carr | Nov 28, 2023

A day in the life of an Optimizely Developer - OptiUKNorth Meetup January 2024

It's time for another UK North Optimizely meet up! After the success of the last one, Ibrar Hussain (26) and Paul Gruffydd (Kin + Carta) will be...

Graham Carr | Nov 28, 2023

Publish content to Optimizely CMS using a custom GPT from OpenAI 🤖

Do you find the traditional editor interface complicated and cluttered? Would you like an editorial AI assistant you can chat with? You can!

Tomas Hensrud Gulla | Nov 28, 2023 | Syndicated blog

Optimizely Graph and Next.js: Building Scalable Headless Solutions

Optimizely Graph harnesses the capabilities of GraphQL, an intuitive and efficient query language to, transform content within an Optimizely CMS in...

Szymon Uryga | Nov 27, 2023

Getting Started with Optimizely SaaS Core and Next.js Integration: Testing Content Updates

The blog post discusses the challenges of content updates on a website using Optimizely CMS, Next.js, and the Apollo Client due to Apollo's local...

Francisco Quintanilla | Nov 27, 2023 | Syndicated blog