Per Hemmingson
Oct 2, 2009
  12502
(6 votes)

Getting EPiServer FileManager into Relate+ clubs

Having the possibility to upload files into EPiServer Community Clubs has internally been a highly requested feature on our Intranet site. Since the EPiServer.FileManger that you see in our Demo templates are based on EPiServer CMS pages and files stored into the current page folder that will not work for Community clubs that are not based on pages.

Well after some discussion with my colleagues the solution was quite simple; Combine how EPiServer Blog uploads file with the Workroom File Manager web control.

First of create an ClubFile page type and add it to your Relate+ project. Then from EPiServer Demo Templates add/take:

  • EPiServer.FileManger Web control
  • The usercontrols in EPiServer.Templates.Demo.FileManager
  • FileManager and extensions images under Templates/Demo/Styles/Default/images
  • Stylesheet specific for Filemanager in styles.css (File manager control, Toolbar buttons, Documents)
  • File Manager language texts from demo_en.xml in lang folder.
  • Lastly, the EPiCheckBox class which is in /Templates/Demo/Workroom/Core/EPiCheckBox.cs

In Web config you register the File Manager Web control,

   1: <configSections>
   2: ...
   3:         <sectionGroup name="episerverModules">            
   4:             <section name="episerver.FileManager" type="EPiServer.Demo.FileManager.Configuration.FileManagerSection, EPiServer.Demo.FileManager"/>
   5:         </sectionGroup>
   6: ...

 

   1: <episerverModules>       
   2:     <episerver.FileManager configSource="Templates\FileManager\views.config" />
   3: </episerverModules>

 

Still in web.config, but in Pages declaration, add

   1: <pages validateRequest="false" enableEventValidation="false">
   2:             <controls>
   3:             ...
   4:                 <add tagPrefix="FileManager" namespace="EPiServer.Demo.FileManager.WebControls" assembly="EPiServer.Demo.FileManager"/>
   5:                 <add tagPrefix="EPiServer" namespace="EPiServer.Templates.RelatePlus.Classes" assembly="EPiServer.Templates.RelatePlus" />
   6:             ...

 

I choose to copy the EPiCheckBox class and changed the namespace to EPiServer.Templates.RelatePlus.Classes.

EPiServer Blog uploads its files into Global Files folder if not reconfigured in web.config. There it creates a xmlrpc folder and from there the tree structure is; PageID, Year, Month, Day.

image

 

My strategy was similar. The File Manager requests a RootFolder Path, so instead of a xmlrpc folder I defined a “ClubFiles” folder and beneath it a folder for each club based on ClubId, but I skipped the date folders. Similar to blogs which worked with PageID.

The code then,

   1: /// <summary>
   2: /// Gets or sets the file folder root.
   3: /// </summary>
   4: /// <value>Path to root folder for files.</value>
   5: public string FileFolderRoot
   6: {
   7:   get
   8:   {
   9:       if (String.IsNullOrEmpty(_fileFolderRoot))
  10:       {
  11:           _fileFolderRoot = GetVPPFolder();
  12:       }
  13:       return _fileFolderRoot;
  14:   }
  15: }
  16: private string GetVPPFolder()
  17: {
  18:     // stolen from how episerver.blogs handle file uploads, changed blog page id to use club id
  19:     string path = "";
  20:     UnifiedDirectory vdir;
  21:     VirtualPathUnifiedProvider provider = GetClubProvider(out vdir);
  22:  
  23:     path =
  24:         VirtualPathUtility.AppendTrailingSlash(VirtualPathUtility.Combine(vdir.VirtualPath,
  25:                                                                           Master.CurrentClub.ID.ToString()));
  26:     UnifiedDirectory clubdir = null;
  27:     if (!(provider.DirectoryExists(path)))
  28:     {
  29:         clubdir = ((UnifiedDirectory)vdir).CreateSubdirectory((Master.CurrentClub.ID.ToString()));
  30:     }
  31:     else
  32:     {
  33:         clubdir = (UnifiedDirectory)provider.GetDirectory(path);
  34:     }
  35:     return clubdir.VirtualPath;
  36: }
  37:  
  38: private VirtualPathUnifiedProvider GetClubProvider(out UnifiedDirectory vdir)
  39: {
  40:     const string vppProviderName = "SiteGlobalFiles";
  41:     const string clubfiles = "clubFiles";
  42:     VirtualPathUnifiedProvider provider = (VirtualPathUnifiedProvider)VirtualPathHandler.GetProvider(vppProviderName);
  43:  
  44:     if (provider.DirectoryExists(provider.VirtualPathRoot + clubfiles))
  45:     {
  46:         vdir = (UnifiedDirectory)provider.GetDirectory(provider.VirtualPathRoot + clubfiles);
  47:     }
  48:     else
  49:     {
  50:         vdir = (UnifiedDirectory)provider.GetDirectory(provider.VirtualPathRoot);
  51:         vdir = vdir.CreateSubdirectory(clubfiles);
  52:     }
  53:     return provider;
  54: }

 

Alright, Lets create an ClubFiles.aspx PageType in our RelatePlus project and set the MasterPageFile to ClubMasterPage. Add the RelatePlus NoClubAccess usercontrol and the File Manager webcontrol,

   1: <%@ Page Language="C#" AutoEventWireup="false" CodeBehind="ClubFiles.aspx.cs" Inherits="EPiServer.Templates.RelatePlus.Pages.ClubFiles"
   2:     MasterPageFile="~/Templates/RelatePlus/MasterPages/ClubMasterPage.master" %>
   3:  
   4: <%@ MasterType VirtualPath="~/Templates/RelatePlus/MasterPages/ClubMasterPage.master" %>
   5: <%@ Register TagPrefix="RelatePlus" TagName="NoClubAccess" Src="~/Templates/RelatePlus/UserControls/ClubUserControls/NoClubAccess.ascx" %>
   6: <asp:Content ID="leftContent" runat="server" ContentPlaceHolderID="plhLeftContentArea">
   7:     <RelatePlus:NoClubAccess ID="ucNoClubAccess" Visible="false" runat="server" />
   8:     <FileManager:FileManagerControl ID="FileManagerControl" runat="server" RootVirtualPath="<%# FileFolderRoot %>" />
   9: </asp:Content>

 

In the code behind, we add the methods described above and databind the FileManagerControl:

   1: protected override void OnLoad(EventArgs e)
   2: {
   3:     // Call base
   4:     base.OnLoad(e);
   5:  
   6:     // Set view options
   7:     if (Master.IsClubAccessable)
   8:     {
   9:  
  10:         if (!IsPostBack)
  11:         {
  12:             FileManagerControl.DataBind();
  13:  
  14:             if (FileManagerControl.CurrentVirtualDirectory == null)
  15:             {
  16:                 GetVPPFolder();
  17:             }
  18:         }
  19:     }
  20:     else
  21:     {
  22:         ucNoClubAccess.Visible = true;
  23:     }
  24: }

 

 

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. Well this will not work for Community clubs, so we need to change it to get the Club Name of that folder.

My 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 HeadingContent we modify the method AppendBreadCrumbs to:

   1: /// <summary>
   2: /// Appends the cookie crumb links to the control supplied 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: }

 

Then the “final” solution looks like this,

image

And in Admin mode, File Management:

image

 

Then you’re done. Now check in your code, get a cup of coffee and let the GUI dude fix the layout stuff.

 

Something that I haven’t done yet but I should is to create my own Virtual path provider. Inherit from EPiServers VPP, override the QueryAccess method and check that the access rights of the files match the current users club access rights. Might be a different blog post.

By the way, I haven’t tested this on live site yet and might have forgotten something. Comments and feedback is appreciated.

Oct 02, 2009

Comments

Sep 21, 2010 10:32 AM

Great Post!
/ Bevan

Karoline Klever
Karoline Klever Sep 21, 2010 10:32 AM

I just tried this out and it works great! The only detail I can think of that you didn't mention was that you need to add a reference to the EPiServer.Demo.Filemanager dll.
Other than that, awesome! Thanks for writing this post :)

Sep 21, 2010 10:32 AM

I've had a very very strange effect from setting up this example.

I've got EPiServer Relate+ 2.0, EPiServer CMS 6.0 and was using the 6.0 demo templates.

Uncommenting the code-behind for the ClubFiles.aspx file DELETED files from the bin directory on-rebuild! Files that were disappearing included but were not limited to - nhibernate.dlll and the microsoft enterprise library DLLs.

I reverted my repository to re-add these files after uncommenting the code, and everything works as it should.

If anybody else has a problem with getting this example working, check your bin directory closely!

Matti Mertojoki
Matti Mertojoki Feb 14, 2013 02:19 PM

Really good article. Just added FileManager from CMS 6 demo templates to Relate 2 R2 Successfully after little tweaking.

There more detailed article about this. I recommend this article if you want to try fileManager with Relate:
http://world.episerver.com/Blogs/Jeff-Wallace/Dates/2009/12/Getting-EPiServer-FileManager-into-Relate-Clubs--Verbose-Version/

Please login to comment.
Latest blogs
Copy Optimizely SaaS CMS Settings to ENV Format Via Bookmarklet

Do you work with multiple Optimizely SaaS CMS instances? Use a bookmarklet to automatically copy them to your clipboard, ready to paste into your e...

Daniel Isaacs | Dec 22, 2024 | Syndicated blog

Increase timeout for long running SQL queries using SQL addon

Learn how to increase the timeout for long running SQL queries using the SQL addon.

Tomas Hensrud Gulla | Dec 20, 2024 | Syndicated blog

Overriding the help text for the Name property in Optimizely CMS

I recently received a question about how to override the Help text for the built-in Name property in Optimizely CMS, so I decided to document my...

Tomas Hensrud Gulla | Dec 20, 2024 | Syndicated blog

Resize Images on the Fly with Optimizely DXP's New CDN Feature

With the latest release, you can now resize images on demand using the Content Delivery Network (CDN). This means no more storing multiple versions...

Satata Satez | Dec 19, 2024

Simplify Optimizely CMS Configuration with JSON Schema

Optimizely CMS is a powerful and versatile platform for content management, offering extensive configuration options that allow developers to...

Hieu Nguyen | Dec 19, 2024

Useful Optimizely CMS Web Components

A list of useful Optimizely CMS components that can be used in add-ons.

Bartosz Sekula | Dec 18, 2024 | Syndicated blog