// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Generic; using System.Globalization; namespace Microsoft.AspNetCore.Mvc.Razor { /// /// A that adds the language as an extension prefix to view names. Language /// that is getting added as extension prefix comes from . /// /// /// For the default case with no areas, views are generated with the following patterns (assuming controller is /// "Home", action is "Index" and language is "en") /// Views/Home/en/Action /// Views/Home/Action /// Views/Shared/en/Action /// Views/Shared/Action /// public class LanguageViewLocationExpander : IViewLocationExpander { private const string ValueKey = "language"; private readonly LanguageViewLocationExpanderFormat _format; /// /// Instantiates a new instance. /// public LanguageViewLocationExpander() : this(LanguageViewLocationExpanderFormat.Suffix) { } /// /// Instantiates a new instance. /// /// The . public LanguageViewLocationExpander(LanguageViewLocationExpanderFormat format) { _format = format; } /// public void PopulateValues(ViewLocationExpanderContext context) { if (context == null) { throw new ArgumentNullException(nameof(context)); } // Using CurrentUICulture so it loads the locale specific resources for the views. context.Values[ValueKey] = CultureInfo.CurrentUICulture.Name; } /// public virtual IEnumerable ExpandViewLocations( ViewLocationExpanderContext context, IEnumerable viewLocations) { if (context == null) { throw new ArgumentNullException(nameof(context)); } if (viewLocations == null) { throw new ArgumentNullException(nameof(viewLocations)); } context.Values.TryGetValue(ValueKey, out var value); if (!string.IsNullOrEmpty(value)) { CultureInfo culture; try { culture = new CultureInfo(value); } catch (CultureNotFoundException) { return viewLocations; } return ExpandViewLocationsCore(viewLocations, culture); } return viewLocations; } private IEnumerable ExpandViewLocationsCore(IEnumerable viewLocations, CultureInfo cultureInfo) { foreach (var location in viewLocations) { var temporaryCultureInfo = cultureInfo; while (temporaryCultureInfo != temporaryCultureInfo.Parent) { if (_format == LanguageViewLocationExpanderFormat.SubFolder) { yield return location.Replace("{0}", temporaryCultureInfo.Name + "/{0}"); } else { yield return location.Replace("{0}", "{0}." + temporaryCultureInfo.Name); } temporaryCultureInfo = temporaryCultureInfo.Parent; } yield return location; } } } }