@@ -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