// Copyright (c) Microsoft Open Technologies, Inc. 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.IO; using System.Linq; namespace Microsoft.AspNet.Mvc.Razor { /// /// Contains methods to locate _ViewStart.cshtml and _GlobalImport.cshtml /// public static class ViewHierarchyUtility { private const string ViewStartFileName = "_ViewStart.cshtml"; private const string GlobalImportFileName = "_GlobalImport.cshtml"; /// /// Gets the view start locations that are applicable to the specified path. /// /// The application relative path of the file to locate /// _ViewStarts for. /// A sequence of paths that represent potential view start locations. /// /// This method returns paths starting from the directory of and /// moves upwards until it hits the application root. /// e.g. /// /Views/Home/View.cshtml -> [ /Views/Home/_ViewStart.cshtml, /Views/_ViewStart.cshtml, /_ViewStart.cshtml ] /// public static IEnumerable GetViewStartLocations(string applicationRelativePath) { return GetHierarchicalPath(applicationRelativePath, ViewStartFileName); } /// /// Gets the locations for _GlobalImports that are applicable to the specified path. /// /// The application relative path of the file to locate /// _GlobalImports for. /// A sequence of paths that represent potential _GlobalImport locations. /// /// This method returns paths starting from the directory of and /// moves upwards until it hits the application root. /// e.g. /// /Views/Home/View.cshtml -> [ /Views/Home/_GlobalImport.cshtml, /Views/_GlobalImport.cshtml, /// /_GlobalImport.cshtml ] /// public static IEnumerable GetGlobalImportLocations(string applicationRelativePath) { return GetHierarchicalPath(applicationRelativePath, GlobalImportFileName); } private static IEnumerable GetHierarchicalPath(string relativePath, string fileName) { if (string.IsNullOrEmpty(relativePath)) { return Enumerable.Empty(); } if (relativePath.StartsWith("~/", StringComparison.Ordinal)) { relativePath = relativePath.Substring(2); } if (relativePath.StartsWith("/", StringComparison.Ordinal)) { relativePath = relativePath.Substring(1); } if (Path.IsPathRooted(relativePath)) { // If the path looks like it's not app relative, don't attempt to construct paths. return Enumerable.Empty(); } if (string.Equals(Path.GetFileName(relativePath), fileName, StringComparison.OrdinalIgnoreCase)) { // If the specified path is for the file hierarchy being constructed, then the first file that applies // to it is in a parent directory. relativePath = Path.GetDirectoryName(relativePath); if (string.IsNullOrEmpty(relativePath)) { return Enumerable.Empty(); } } var locations = new List(); while (!string.IsNullOrEmpty(relativePath)) { relativePath = Path.GetDirectoryName(relativePath); var path = Path.Combine(relativePath, fileName); locations.Add(path); } return locations; } } }