How to Redirect the Umbraco Media Path to Another Location
Today we have a guest post from my cousin, David Prothero, who is now implementing Umbraco for his company.
They recently figured out a solution to a problem that we hadn't had before so I asked him to write up something so he could share the knowledge with the rest of the community.
Enjoy!
Our company recently selected Umbraco as the CMS for a new product we are developing. Having developed products on a home-grown CMS for years, we’d learned one very important lesson when developing these systems:
Keep user managed content and developer managed code separate.
Developer managed code should be kept in a source control system (we use git) and user managed content should, ideally, be in the database or at least in a centrally managed location. As those who work with Umbraco probably know, the system stores most content in the database. However, it saves images, CSS, views, macros, and other media on the filesystem, in the directory where your Umbraco site lives.
This directory is where we have our git repository initialized from. For CSS, views, and macros, we found this acceptable. These things will be managed by the developers. There are even some static images that will be handled by the developers, so for this we just created a ~/static-images / folder and let git manage those files as well.
That left us with the ~/oldmedia/ folder…definitely user managed content. We needed a way to be able to redirect this to another location. Searching our.umbraco.com led us to the ~/Config/FileSystemProviders.config file, in which the stock version has something like:
<Provider alias="media" type="Umbraco.Core.IO.PhysicalFileSystem, Umbraco.Core"> <Parameters> <add key="virtualRoot" value="~/media/" /> </Parameters> </Provider>
OK, simple, we just change the “virtualRoot” key to point to another folder, right? Yes and no…Umbraco requires that the path begin with “~/”. In other words, the path has to be within your Umbraco web site. It makes sense when you know how Umbraco works. It needs two things: 1) a path that it has control over to write uploaded files to, and 2) a path that is accessible via http URL so it can include the images in pages it serves to browsers.
We started thinking we were going to have to setup a virtual directory in IIS so that Umbraco would think that the path was part of the website, but we could then direct it to another location. This may yet work for people, but we decided against it in order to keep the IIS configuration as stock as possible and allow developers to run IISExpress on their local machines.
In almost desperation, we looked in the Umbraco source code, particularly at the Umbraco.Core.IO.PhysicalFileSystem class you can see mentioned in the config file above. What we found was that there were two other parameters, not discussed in the Umbraco documentation…”rootPath” and “rootUrl”. Our config now looks like this:
<Provider alias="media" type="Umbraco.Core.IO.PhysicalFileSystem, Umbraco.Core"> <Parameters> <add key="rootPath" value="\\[ourdomain].net\dfstest\Media" /> <add key="rootUrl" value="http://media.[ourdomain].net/media/" /> </Parameters> </Provider>
“rootPath” specifies a Windows filesystem path where Umbraco can save uploaded files. It’s a standard Windows file path (not a URL path). In our example, we are using a DFS path so the files will be highly available anywhere on our network.
“rootUrl” is the URL that Umbraco will prepend to the media filename when rendering pages to browsers. There needs to be some kind of web server listening to this URL and that URL needs to map to the physical Windows path specified in rootPath (or at least a replicated copy of it). In our case, we setup an IIS website, but it could even be Apache or something else. It doesn’t matter. In fact, we are considering having the rootUrl point to an Amazon S3 bucket with a background process that replicates from the DFS path on our network to the Amazon S3 bucket.
Since this was an undocumented configuration setting, we thought we would share our findings with the world. Hopefully this is something you can use.
- David Prothero, July 2013