Reputation: 28064
I have an ASP.NET MVC 3 site using a custom route for specifying the language in the URL like so:
routes.MapRoute("Default", "{culture}/{controller}/{action}/{id}",
new { controller = "Home", action = "Index", culture = "en", id = UrlParameter.Optional });
My base controller then sets the current thread culture appropriately in its OnActionExecuting event like so:
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
var culture = filterContext.RouteData.Values["culture"] ?? "en";
var cultureInfo = CultureInfo.GetCultureInfo((string)culture);
Thread.CurrentThread.CurrentCulture = cultureInfo;
Thread.CurrentThread.CurrentUICulture = cultureInfo;
base.OnActionExecuting(filterContext);
}
Wherever I need a locale-specific string in my view, I reference the resource appropriately:
<img src="@Url.Content(Resources.Paths.ChallengeLogo)" alt="@Resources.Strings.AltChallengeLogo" class="logo" />
However, for images, the URL (src="...") will follow a convention "~/Content/Culture/Images/Whatever.jpg", and I'd rather not have to manually maintain a resource file for each image location. In short, what I'd prefer to do is:
<img src="@Url.Content("Images/ChallengeLogo.png")" alt="@Resources.Strings.AltChallengeLogo" class="logo" />
In this scenario, the Url.Content method would apply the path convention and translate the src attribute value to, for example:
/Content/en-US/Images/ChallengeLogo.png
/Content/en-GB/Images/ChallengeLogo.png
/Content/de/Images/ChallengeLogo.png
etc...
I don't have to use Url.Content specifically. I'm more than willing to create an extension method for this purpose, but I'm not sure if I'm even taking the best approach. What is the standard approach here?
Edit: I ended up creating an helper. The helper has the added benefit of checking that the path to the current culture actually exists, or falling back to the parent / default culture if necessary. Code below:
private static CultureInfo _defaultCulture = CultureInfo.GetCultureInfo("en");
public static string Localized(this UrlHelper url, string pathTemplate)
{
var server = url.RequestContext.HttpContext.Server;
var culture = Thread.CurrentThread.CurrentUICulture;
var localizedPath = string.Format(pathTemplate, culture.Name);
var physicalPath = server.MapPath(localizedPath);
while (!File.Exists(physicalPath) && culture.Parent != null)
{
culture = culture.Parent;
localizedPath = string.Format(pathTemplate, culture.Name);
physicalPath = server.MapPath(localizedPath);
}
if (!File.Exists(physicalPath))
localizedPath = string.Format(pathTemplate, _defaultCulture.Name);
return url.Content(localizedPath);
}
In my views, I can use this helper as follows:
<div class="toolbox">
<a href="#" class="button register">
<img src="@Url.Localized("~/Content/Localized/{0}/Images/Button_Register.png")"
alt="@Resources.Strings.AltRegisterButton" /></a>
<a href="#" class="button login">
<img src="@Url.Localized("~/Content/Localized/{0}/Images/Button_Login.png")"
alt="@Resources.Strings.AltLoginButton" /></a>
</div>
Upvotes: 3
Views: 7500
Reputation: 1018
Well, I haven't actually done it but I came across this post when looking for someone who actually did.
I was thinking that you could extend the StaticFileHandler to first look for some "localized" version of a static file before serving the actual file.
Something like, when serving http://yoursite.com/Content/images/logo.jpg
** this may all be bound to the fact that /Content/images/logo.jpg MUST exist, as that is the way the StaticFileHandler would be triggered in the first place.
If I end up doing that, I'll write up a blog post and share a link here.
UPDATE: Did implement it as I mentioned, though it ended up being a custom HttpHandler instead of an extension of the StaticFileHandler: http://www.prosoftnearshore.com/2011/10/localizing-files-jpg-css-js-etc-in-asp-net/
Upvotes: 0
Reputation: 2999
I think your suggestion is the first one that came to my mind too. You can easily solve this with creating your own html helper that constructs the localized url. See http://develoq.net/2011/how-to-create-custom-html-helpers-for-asp-net-mvc-3-and-razor-view-engine/ as an example for creating a custom html helper.
Upvotes: 3