Per Hemmingson
Oct 2, 2009
  12492
(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
How to Elevate Your Experimentation - Opticon workshop experience

As a non-expert in the field of experimentation, I’d like to share my feedback on the recent Opticon San Antonio workshop session titled "How to...

David Ortiz | Dec 11, 2024

Persisting a Strawberry Shake GraphQL Client for Optimizely's Content Graph

A recent CMS project used Strawberry Shake to generate an up-to-date C# GraphQL client at each build. But what happens to the build if the GraphQL...

Nicholas Sideras | Dec 11, 2024 | Syndicated blog

Opti ID with Secure Cookies And Third Party AddOns

Opti ID has revolutionised access to the Optimizely One suite and is now the preferred authentication method on all PAAS CMS websites that I build....

Mark Stott | Dec 9, 2024

AsyncHelper can be considered harmful

.NET developers have been in the transition to move from synchronous APIs to asynchronous API. That was boosted a lot by await/async keyword of C#...

Quan Mai | Dec 4, 2024 | Syndicated blog