Skip to content

Commit b77521c

Browse files
committed
Web.Routing - cleanup template / rendering engine lookup
1 parent 58b91fe commit b77521c

File tree

3 files changed

+71
-60
lines changed

3 files changed

+71
-60
lines changed
Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
namespace Umbraco.Core
22
{
3-
public enum RenderingEngine
4-
{
5-
Mvc,
6-
WebForms
7-
}
3+
public enum RenderingEngine
4+
{
5+
Unknown,
6+
Mvc,
7+
WebForms
8+
}
89
}

src/Umbraco.Web/Routing/PublishedContentRequest.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ namespace Umbraco.Web.Routing
2424
{
2525
/// <summary>
2626
/// Represents a request for one specified Umbraco IPublishedContent to be rendered
27-
/// by one specified Template, using one specified Culture and RenderingEngine.
27+
/// by one specified template, using one specified Culture and RenderingEngine.
2828
/// </summary>
2929
internal class PublishedContentRequest
3030
{
@@ -117,7 +117,7 @@ internal void OnPrepared()
117117
/// <summary>
118118
/// Gets or sets the requested content.
119119
/// </summary>
120-
/// <remarks>Setting the requested content clears both <c>Template</c> and <c>AlternateTemplateAlias</c>.</remarks>
120+
/// <remarks>Setting the requested content clears <c>Template</c>.</remarks>
121121
public IPublishedContent PublishedContent
122122
{
123123
get { return _publishedContent; }
@@ -181,7 +181,7 @@ public bool HasPublishedContent
181181
/// </summary>
182182
public bool HasTemplate
183183
{
184-
get { return this.Template != null ; }
184+
get { return this.Template != null; }
185185
}
186186

187187
#endregion

src/Umbraco.Web/Routing/PublishedContentRequestEngine.cs

Lines changed: 62 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -237,63 +237,73 @@ private void HandleWildcardDomains()
237237

238238
#region Rendering engine
239239

240+
/// <summary>
241+
/// Finds the rendering engine to use to render a template specified by its alias.
242+
/// </summary>
243+
/// <param name="alias">The alias of the template.</param>
244+
/// <returns>The rendering engine, or Unknown if the template was not found.</returns>
245+
internal RenderingEngine FindTemplateRenderingEngine(string alias)
246+
{
247+
if (string.IsNullOrWhiteSpace(alias))
248+
return RenderingEngine.Unknown;
249+
250+
alias = alias.Replace('\\', '/'); // forward slashes only
251+
252+
// NOTE: we could start with what's the current default?
253+
254+
if (FindTemplateRenderingEngineInDirectory(new DirectoryInfo(IOHelper.MapPath(SystemDirectories.MvcViews)),
255+
alias, new[] { ".cshtml", ".vbhtml" }))
256+
return RenderingEngine.Mvc;
257+
258+
if (FindTemplateRenderingEngineInDirectory(new DirectoryInfo(IOHelper.MapPath(SystemDirectories.Masterpages)),
259+
alias, new[] { ".master" }))
260+
return RenderingEngine.WebForms;
261+
262+
return RenderingEngine.Unknown;
263+
}
264+
265+
internal bool FindTemplateRenderingEngineInDirectory(DirectoryInfo directory, string alias, string[] extensions)
266+
{
267+
if (directory == null || !directory.Exists)
268+
return false;
269+
270+
var pos = alias.IndexOf('/');
271+
if (pos > 0)
272+
{
273+
// recurse
274+
var subdir = directory.GetDirectories(alias.Substring(0, pos)).FirstOrDefault();
275+
alias = alias.Substring(pos + 1);
276+
return subdir == null ? false : FindTemplateRenderingEngineInDirectory(subdir, alias, extensions);
277+
}
278+
else
279+
{
280+
// look here
281+
return directory.GetFiles().Any(f => extensions.Any(e => f.Name.InvariantEquals(alias + e)));
282+
}
283+
}
284+
240285
/// <summary>
241286
/// Finds the rendering engine to use, and updates the PublishedContentRequest accordingly.
242287
/// </summary>
243288
internal void FindRenderingEngine()
244289
{
245-
//First, if there is no template, we will default to use MVC because MVC supports Hijacking routes which
246-
//sometimes don't require a template since the developer may want full control over the rendering.
247-
//Webforms doesn't support this so MVC it is. MVC will also handle what to do if no template or hijacked route
248-
//is there (i.e. blank page)
249-
if (!_pcr.HasTemplate)
250-
{
251-
_pcr.RenderingEngine = RenderingEngine.Mvc;
252-
return;
253-
}
254-
255-
//NOTE: Not sure how the alias is actually saved with a space as this shouldn't ever be the case?
256-
// but apparently this happens. I think what should actually be done always is the template alias
257-
// should be saved using the ToUmbracoAlias method and then we can use this here too, that way it
258-
// it 100% consistent. I'll leave this here for now until further invenstigation.
259-
var templateAlias = _pcr.Template.Alias.Replace(" ", string.Empty);
260-
//var templateAlias = _pcr.Template.Alias.ToUmbracoAlias(StringAliasCaseType.PascalCase);
261-
262-
Func<DirectoryInfo, string, string[], RenderingEngine, bool> determineEngine =
263-
(directory, alias, extensions, renderingEngine) =>
264-
{
265-
//so we have a template, now we need to figure out where the template is, this is done just by the Alias field
266-
//ensure it exists
267-
if (!directory.Exists) Directory.CreateDirectory(directory.FullName);
268-
var file = directory.GetFiles()
269-
.FirstOrDefault(x => extensions.Any(e => x.Name.InvariantEquals(alias + e)));
270-
271-
if (file != null)
272-
{
273-
//it is mvc since we have a template there that exists with this alias
274-
_pcr.RenderingEngine = renderingEngine;
275-
return true;
276-
}
277-
return false;
278-
};
279-
280-
//first determine if it is MVC, we will favor mvc if there is a template with the same name in both
281-
// folders, if it is then MVC will be selected
282-
if (!determineEngine(
283-
new DirectoryInfo(IOHelper.MapPath(SystemDirectories.MvcViews)),
284-
templateAlias,
285-
new[] { ".cshtml", ".vbhtml" },
286-
RenderingEngine.Mvc))
287-
{
288-
//if not, then determine if it is webforms (this should def match if a template is assigned and its not in the MVC folder)
289-
// if it doesn't match, then MVC will be used by default anyways.
290-
determineEngine(
291-
new DirectoryInfo(IOHelper.MapPath(SystemDirectories.Masterpages)),
292-
templateAlias,
293-
new[] { ".master" },
294-
RenderingEngine.WebForms);
295-
}
296-
290+
RenderingEngine renderingEngine = RenderingEngine.Unknown;
291+
292+
// NOTE: Not sure how the alias is actually saved with a space as this shouldn't ever be the case?
293+
// but apparently this happens. I think what should actually be done always is the template alias
294+
// should be saved using the ToUmbracoAlias method and then we can use this here too, that way it
295+
// it 100% consistent. I'll leave this here for now until further invenstigation.
296+
if (_pcr.HasTemplate)
297+
renderingEngine = FindTemplateRenderingEngine(_pcr.Template.Alias.Replace(" ", ""));
298+
299+
// Unkwnown means that no template was found. Default to Mvc because Mvc supports hijacking
300+
// routes which sometimes doesn't require a template since the developer may want full control
301+
// over the rendering. Can't do it in WebForms, so Mvc it is. And Mvc will also handle what to
302+
// do if no template or hijacked route is exist.
303+
if (renderingEngine == RenderingEngine.Unknown)
304+
renderingEngine = RenderingEngine.Mvc;
305+
306+
_pcr.RenderingEngine = renderingEngine;
297307
}
298308

299309
#endregion

0 commit comments

Comments
 (0)