Since a couple of versions back, Sitecore has decided to (by default) replace all spaces in a url by dashes.
While this seems like a good idea (mainly for SEO reasons) it also brings with it it's own set of issues, mainly when an item has dashes in it's name.
More information about why this is bad can be found on Jammykam's excellent blog posts about it:
Now, onto the specifics. We had an issue where clients would upload media files (in this case pdf files) which contained a mix of dashes, spaces, underscores, you name it.
Normally this wouldn't be an issue but due to the fact that all URLs would be resolved as
--- instead of
- things started going wrong.
We didn't have any issues with normal pages as the names used there were quite clean. Ideally we would of course train the client to use proper item names and everything would be fine, but as we all know that doesn't always work...
Looking around for a possible solution we noticed that Sitecore uses the
encodeNameReplacements for both normal "page" items and media items.
Wouldn't it be nice if we had a separate configuration for media items? And isn't it nice that Sitecore allows us to override almost anything?
I think you can see where this is going... A custom MediaProvider!
The class we had to override was the
Sitecore.Resources.Media.MediaProvider, and more specifically the
I won't bore you with the specifics, these can all be found in the full source code on Github, but I'll explain some of the finer points.
Most importantly about this new
MediaProvider is this line:
var imageUrlPath = CustomEncode(!options.UseItemPath || !path.StartsWith(_MEDIA_LIBRARY_PATH, StringComparison.OrdinalIgnoreCase) ? item.ID.ToShortID().ToString() : StringUtil.Mid(path, _MEDIA_LIBRARY_PATH.Length), '/');
Here we've replaced Sitecore's standard logic to encode URLs with a custom one which will use our custom set of media replacements.
We've also tried to keep things as aligned with Sitecore as possible, emulating the way their setup works.
With all this set up all we need to do is replace the standard
MediaProvider with our own custom implementation and add the new "media replacements" which will allow us to define that spaces need to be converted to
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:set="http://www.sitecore.net/xmlconfig/set/" > <sitecore> <mediaLibrary> <mediaProvider type="Sitecore.Resources.Media.MediaProvider, Sitecore.Kernel"> <patch:attribute name="type" value="Boondoggle.Sc.Media.MediaProvider, Boondoggle.Sc.MediaProvider" /> </mediaProvider> </mediaLibrary> <encodeMediaReplacements> <replace mode="on" find="&" replaceWith=",-a-," /> <replace mode="on" find="?" replaceWith=",-q-,"/> <replace mode="on" find="/" replaceWith=",-s-,"/> <replace mode="on" find="*" replaceWith=",-w-,"/> <replace mode="on" find="." replaceWith=",-d-,"/> <replace mode="on" find=":" replaceWith=",-c-,"/> <replace mode="on" find=" " replaceWith="%20"/> </encodeMediaReplacements> </sitecore> </configuration>
And that's it! I have one more post incoming about how Sitecore seems to handle 404 on missing media items uploaded as file. Just to tease you a bit into what's coming.
And as always, full source code on Github: https://github.com/fverswijver/Boondoggle.Sc.MediaProvider