A critical vulnerability was discovered in React Server Components (Next.js). Our systems remain protected but we advise to update packages to newest version. Learn More

Jeff Wallace
Dec 1, 2009
  5620
(0 votes)

Getting EPiServer FileManager into Relate+ Clubs – Verbose Version

In October, Per Hemmingson wrote a great blog regarding how to implement the CMS file manager in Relate+ Clubs

The CMS File Manager includes robust functionality not included in the Community Document Archive API’s.  Per’s solution to take advantage of the CMS functionality is excellent!  After implementing it myself I thought some people might benefit from having a verbose version of the all of the necessary steps.  For some this may be overkill.  For others it may be helpful.  You’ll probably notice I borrowed some of Per’s blog verbiage. Fortunately he’s OK with this.  :)  All credit for the solution should go to Per.   

The following steps will help you get started in setting this up for your Relate+ site.  Obviously this is simply an example and can be tweaked according to your need.

  1. Open the Visual Studio project for the Relate+ site titled EPiServer.Templates.RelatePlus.csproj from the sites root directory (e.g. C:\EPiServer\Sites\<site name>\).
  2. In the project, under /Templates/RelatePlus/Pages, create a new page template called “ClubFiles”.image
    1. For more information on creating page templates visit the “how to” page on EPiServer Page Templates.
  3. Ensure the associated page type is added to CMS in Admin mode.                                                                    image

    1. For more information on creating page types visit the “how to” page on EPiServer Master Pages.
  4. The next several steps require copying files from the EPiServer Demo Templates. If you do not have these templates installed visit EPiServer Demo Templates and follow the instructions to install them.
  5. Then from EPiServer Demo Templates:

    FileManager WebControl

      1. Copy the FileManager WebControl assembly(EPiServer.Demo.Filemanager.dll) from the bin directory of a site that has the Demo templates installed over to the Relate+ site bin directory (e.g. C:\EPiServer\Sites\<site name>\bin).
      2. In your Visual Studio project add a reference to the EPiServer.Demo.Filemanager assembly.
        1. **NOTE: Since WebControls only require the use of the assembly, not the actual code,  adding the code files to the project is not necessary here.  In other steps below you will need to copy the code.

    FileManager User Controls

    1. Create a “Demo” folder as a sub-folder of “Templates” in the Relate+ project .
    2. Copy the entire contents of the  File Manager UserControl folder (e.g. C:\EPiServer\Sites\<my site>\Templates\Demo\FileManager) to the “Demo” folder of the Relate+ project.  The easiest way to do this is to drag-and-drop the folder from Windows Explorer to the new “Demo” folder in the Visual Studio Relate+ project.image
    3. Create a “Styles” folder in the Relate+ project as a subfolder of /Templates/Demo.
    4. Create a “Default” folder as a subfolder of /Templates/Demo/Styles.
    5. Create a “Images” folder as a subfolder of /Templates/Demos/Default/Styles.
    6. Copy the entire contents of the “FileManager” and “extensions” folders to the previously created “Images” folder.  The easiest way to do this is to drag-and-drop the folders from Windows Explorer to the new “Images” folder in the Visual Studio Relate+ project. 
    7. Copy the stylesheet Styles.css to the previously created “Images” folder.            image
    8. Open the Styles.css stylesheet.
    9. All items in the stylesheet are not necessary.  Remove everything but the sections titled: “Documents”, “File Manager Control”, and “Toolbar BUTTONS” to avoid conflicts.
    10. Open /RelatePlus/UserControls/Headers.ascx.
    11. In the Header.ascx file add a reference to the Styles.css stylesheet:
      Code Snippet
      1. <link rel="stylesheet" media="screen" href='<%=ResolveUrl("~/Templates/Demo/Styles/Default/Styles.css") %>' type="text/css" />

     

    Language File

    1. Include the FileManager language text by copying file demo_EN.xml from the Demo Templates lang folder (e.g. C:\EPiServer\Sites\<my site>\lang) to your Relate+ sites lang folder (e.g. C:\EPiServer\Sites\<my site>\lang).  The easiest way to do this is to drag-and-drop the file from Windows Explorer to the new “lang” folder in the Visual Studio Relate+ project. 

    Checkbox

    1. Create a new folder under the root called "Classes" in the Relate+ project.
    2. Copy the file EPiCheckBox.cs from the Demo /Templates /Templates/Demo/Workroom/Core to the new "Classes" folder.image
    3. Open the file EPiCheckBox.cs file.
    4. Change the namespace to "EPiServer.Templates.RelatePlus.Classes".
    5. Change the registration of the checkbox control in /Templates/Demo/FileManager/FileList.ascx to the appropriate Assembly and Namespace. Initially it is set to:
      Code Snippet
      1. <%@ Register TagPrefix="EPiServer" Assembly="EPiServer.Templates.Demo" Namespace="EPiServer.Templates.Demo.Workroom.Core" %>
    6. Based on these instructions it should be changed to:
      Code Snippet
      1. <%@ Register TagPrefix="EPiServer" Assembly="EPiServer.Templates.RelatePlus" Namespace="EPiServer.Templates.RelatePlus.Classes" %>
    7. The FileManager VersionList also uses the checkbox class.  Change the registration of the checkbox control in /Templates/Demo/FileManager/VersionList.ascx to the appropriate assembly and namespace. Follow the same steps as the last two above in the VersionList.ascx file.
  6. In web.config register the File Manager Web control:

      Code Snippet
      1. <configuration>
      2.   <configSections>
      3.     
      4. ...
      5.  
      6.     <sectionGroup name="episerverModules">
      7.       <section name="episerver.FileManager" type="EPiServer.Demo.FileManager.Configuration.FileManagerSection, EPiServer.Demo.FileManager"/>
      8.     </sectionGroup>
      9.  
      10.     ...
      11.   
      12.   </configSections>
  7. Add one more addition to the tail of web.config:
      Code Snippet
      1.   </applicationSettings>
      2.   <episerverModules>
      3.     <episerver.FileManager configSource="Templates\Demo\FileManager\views.config" />
      4.   </episerverModules>
      5. </configuration>
  8. Still in the web.config, but in the Pages declaration, add:
      Code Snippet
      1. <pages validateRequest="false" enableEventValidation="false">
      2.       <controls>
      3.  
      4.         ...
      5.         
      6.         <add tagPrefix="FileManager" namespace="EPiServer.Demo.FileManager.WebControls" assembly="EPiServer.Demo.FileManager"/>
      7.         <add tagPrefix="EPiServer" namespace="EPiServer.Templates.RelatePlus.Classes" assembly="EPiServer.Templates.RelatePlus" />        
      8.       </controls>
      9.     </pages>
  9. You will need to add some additional “using” statements to get the code to compile.  The final code behind file, including these using statements, appears as follows:
      Code Snippet
      1. using System;
      2. using System.Collections.Generic;
      3. using System.Web;
      4. using System.Web.UI;
      5. using System.Web.UI.WebControls;
      6. using System.Web.UI.HtmlControls;
      7. using EPiServer;
      8. using EPiServer.Core;
      9. using EPiServer.DataAbstraction;
      10. using EPiServer.Web.WebControls;
      11.  
      12. using EPiServer.Web.Hosting;
      13. using EPiServer.Demo.FileManager;
      14. using EPiServer.Community.Club;
      15. using EPiServer.Templates.RelatePlus.Classes;
      16. using EPiServer.BaseLibrary;
      17.  
      18. namespace EPiServer.Templates.RelatePlus.Templates.RelatePlus.Pages
      19. {
      20.     public partial class ClubFiles : EPiServer.Templates.RelatePlus.Pages.Base.PageBase
      21.     {
      22.         private string _fileFolderRoot;
      23.  
      24.         /// <summary>
      25.         /// Gets or sets the file folder root.
      26.         /// </summary>
      27.         /// <value>Path to root folder for files.</value>
      28.         public string FileFolderRoot
      29.         {
      30.             get
      31.             {
      32.                 if (String.IsNullOrEmpty(_fileFolderRoot))
      33.                 {
      34.                     _fileFolderRoot = GetVPPFolder();
      35.                 }
      36.                 return _fileFolderRoot;
      37.             }
      38.         }
      39.  
      40.         protected void Page_Load(object sender, EventArgs e)
      41.         {
      42.                 
      43.         }
      44.         protected override void OnLoad(EventArgs e)
      45.         {
      46.             // Call base
      47.             base.OnLoad(e);
      48.  
      49.             // Set view options
      50.             if (Master.IsClubAccessable)
      51.             {
      52.                 if (!IsPostBack)
      53.                 {
      54.                     FileManagerControl.DataBind();
      55.                     
      56.                     if (FileManagerControl.CurrentVirtualDirectory == null)
      57.                     {
      58.                         GetVPPFolder();
      59.                     }
      60.                 }
      61.             }
      62.             else
      63.             {
      64.                 ucNoClubAccess.Visible = true;
      65.             }
      66.         }
      67.  
      68.         private string GetVPPFolder()
      69.         {
      70.             // stolen from how episerver.blogs handle file uploads, changed blog page id to use club id
      71.             string path = "";
      72.             UnifiedDirectory vdir;
      73.             var provider = GetClubProvider(out vdir);
      74.  
      75.             path =  VirtualPathUtility.AppendTrailingSlash(VirtualPathUtility.Combine(vdir.VirtualPath,
      76.                 Master.CurrentClub.ID.ToString()));
      77.             UnifiedDirectory clubdir = null;
      78.             
      79.             if (!(provider.DirectoryExists(path)))
      80.             {
      81.                 clubdir = ((UnifiedDirectory)vdir).CreateSubdirectory((Master.CurrentClub.ID.ToString()));
      82.             }
      83.             else
      84.             {
      85.                 clubdir = (UnifiedDirectory)provider.GetDirectory(path);
      86.             }
      87.             return clubdir.VirtualPath;
      88.         }  
      89.         
      90.         private VirtualPathVersioningProvider GetClubProvider(out UnifiedDirectory vdir)
      91.         {
      92.             const string vppProviderName = "SiteGlobalFiles";
      93.             const string clubfiles = "clubFiles";
      94.             var provider = (VirtualPathVersioningProvider)VirtualPathHandler.GetProvider(vppProviderName);
      95.  
      96.             if (provider.DirectoryExists(provider.VirtualPathRoot + clubfiles))
      97.             {
      98.                 vdir = (UnifiedDirectory)provider.GetDirectory(provider.VirtualPathRoot + clubfiles);
      99.             }
      100.             else
      101.             {
      102.                 vdir = (UnifiedDirectory)provider.GetDirectory(provider.VirtualPathRoot);
      103.                 vdir = vdir.CreateSubdirectory(clubfiles);
      104.             }
      105.             return provider;
      106.         }
      107.     }
      108. }
  10. Navigate to CMS Admin mode.
  11. Select the “Page Type” tab.
  12. Under “Page Types” select “Clubs”.
  13. Select the “Settings” button.
  14. Select the “Available Page Types” tab.
  15. Ensure that the “ClubFiles” checkbox is selected.  This will allow ClubFiles page types to be added underneath Clubs page types.
  16. Select “Save”.
  17. Navigate to Edit mode.
  18. In the structure, select “Clubs”.
  19. Right click and select “Create New”.
  20. Select the “ClubFiles” page type.
  21. Give it a Name such as “Files”.
  22. Select the “Save and Publish” button.
  23. In the site tree structure select “Clubs”.
  24. Select the “CreateClub” button on your Clubs page.
  25. Create a “Club Name” (e.g. “MySampleClub” and note the new “Files” tab! image

Fixing the Bread Crumb

The File Manager is built for EPiServer CMS Pages and the bread crumb control expects the files to be in the page’s directory, where it gets the page owner and displays the Page Name. This will not work for Community/Relate+ clubs, so we need to change it to get the Club Name of that folder.

The current solution is a quick hack where it tries to parse the folder name, which is the club id and then get that club. Anyhow, in the usercontrol /Templates/Demo/FileManager/HeadingContent.ascx we modify the method AppendBreadCrumbs to:

Code Snippet
  1. /// <summary>
  2.         /// Appends the cookie crumb links to the control upplied as targetControl.
  3.         /// </summary>
  4.         /// <param name="currentDirectory">The current directory.</param>
  5.         /// <param name="targetControl">The target control to append cookie crumb links to.</param>
  6.         private void AppendBreadCrumbs(UnifiedDirectory currentDirectory, Control targetControl)
  7.         {            
  8.             if (currentDirectory == null || FileManager.RootVirtualPath == currentDirectory.VirtualPath)
  9.             {
  10.                 // Reset the link enumeration when we reach the topmost directory.
  11.                 _linkId = 0;
  12.             }
  13.             else
  14.             {
  15.                 // Append cookie crumb for the parent directory before adding for the current directory.
  16.                 AppendBreadCrumbs(currentDirectory.Parent, targetControl);
  17.                 Literal slash = new Literal();
  18.                 slash.Text = " / ";
  19.                 targetControl.Controls.Add(slash);
  20.             }
  21.  
  22.             string directoryName = currentDirectory.Name;
  23.             if (currentDirectory.Parent != null)
  24.             {
  25.                 int clubID;
  26.                 // a hack to make it work. Will try parse all folders
  27.                 if (int.TryParse(currentDirectory.Name, out clubID))
  28.                 {
  29.                     Club currentClub = ClubHandler.GetClub(clubID);
  30.  
  31.                     if (currentClub != null)
  32.                     {
  33.                         directoryName = currentClub.Name;
  34.                     }
  35.                 }
  36.             }
  37.  
  38.             LinkButton b = new LinkButton();
  39.             b.ID = "link" + _linkId++;
  40.             b.Text = directoryName;
  41.             b.CommandArgument = currentDirectory.VirtualPath;
  42.             b.CommandName = FileManagerCommandName.SelectFolder;
  43.             b.Command += new CommandEventHandler(RaiseCommand);
  44.             targetControl.Controls.Add(b);
  45.         }

Be sure to add the appropriate using statement for the Club class at the head of the AppendBreadCrumbs file:

using EPiServer.Community.Club;

Then the “final” solution looks like this:

image

And in Admin mode, File Management:

image

That’s it!  The file manager should now be working in your Relate+ site. 

 

Comments and feedback are welcome.

Dec 01, 2009

Comments

Please login to comment.
Latest blogs
A day in the life of an Optimizely OMVP: Learning Optimizely Just Got Easier: Introducing the Optimizely Learning Centre

On the back of my last post about the Opti Graph Learning Centre, I am now happy to announce a revamped interactive learning platform that makes...

Graham Carr | Jan 31, 2026

Scheduled job for deleting content types and all related content

In my previous blog post which was about getting an overview of your sites content https://world.optimizely.com/blogs/Per-Nergard/Dates/2026/1/sche...

Per Nergård (MVP) | Jan 30, 2026

Working With Applications in Optimizely CMS 13

💡 Note:  The following content has been written based on Optimizely CMS 13 Preview 2 and may not accurately reflect the final release version. As...

Mark Stott | Jan 30, 2026

Experimentation at Speed Using Optimizely Opal and Web Experimentation

If you are working in experimentation, you will know that speed matters. The quicker you can go from idea to implementation, the faster you can...

Minesh Shah (Netcel) | Jan 30, 2026

How to run Optimizely CMS on VS Code Dev Containers

VS Code Dev Containers is an extension that allows you to use a Docker container as a full-featured development environment. Instead of installing...

Daniel Halse | Jan 30, 2026

A day in the life of an Optimizely OMVP: Introducing Optimizely Graph Learning Centre Beta: Master GraphQL for Content Delivery

GraphQL is transforming how developers query and deliver content from Optimizely CMS. But let's be honest—there's a learning curve. Between...

Graham Carr | Jan 30, 2026