Calling all developers! We invite you to provide your input on Feature Experimentation by completing this brief survey.

 

Per Hemmingson
Oct 2, 2009
  12513
(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
Optimizely Content Graph on mobile application

CG everywhere! I pull schema from our default index https://cg.optimizely.com/app/graphiql?auth=eBrGunULiC5TziTCtiOLEmov2LijBf30obh0KmhcBlyTktGZ in...

Cuong Nguyen Dinh | Jan 20, 2025

Image Analyzer with AI Assistant for Optimizely

The Smart Image Analyzer is a new feature in the Epicweb AI Assistant for Optimizely CMS that automates the management of image metadata, such as...

Luc Gosso (MVP) | Jan 16, 2025 | Syndicated blog

How to: create Decimal metafield with custom precision

If you are using catalog system, the way of creating metafields are easy – in fact, you can forget about “metafields”, all you should be using is t...

Quan Mai | Jan 16, 2025 | Syndicated blog

Level Up with Optimizely's Newly Relaunched Certifications!

We're thrilled to announce the relaunch of our Optimizely Certifications—designed to help partners, customers, and developers redefine what it mean...

Satata Satez | Jan 14, 2025

Introducing AI Assistance for DBLocalizationProvider

The LocalizationProvider for Optimizely has long been a powerful tool for enhancing the localization capabilities of Optimizely CMS. Designed to ma...

Luc Gosso (MVP) | Jan 14, 2025 | Syndicated blog

Order tabs with drag and drop - Blazor

I have started to play around a little with Blazor and the best way to learn is to reimplement some old stuff for CMS12. So I took a look at my old...

Per Nergård (MVP) | Jan 14, 2025