diff --git a/src/Umbraco.Web/Routing/PublishedContentRequest.cs b/src/Umbraco.Web/Routing/PublishedContentRequest.cs index 36e7fb5d26..093b942a33 100644 --- a/src/Umbraco.Web/Routing/PublishedContentRequest.cs +++ b/src/Umbraco.Web/Routing/PublishedContentRequest.cs @@ -275,6 +275,7 @@ namespace Umbraco.Web.Routing /// /// Gets or sets the requested content. /// + /// Setting the requested content clears both Template and AlternateTemplateAlias. public IPublishedContent PublishedContent { get { return _publishedContent; } @@ -282,6 +283,7 @@ namespace Umbraco.Web.Routing { _publishedContent = value; this.Template = null; + this.AlternateTemplateAlias = null; _nodeId = _publishedContent != null ? _publishedContent.Id : 0; } } @@ -299,6 +301,16 @@ namespace Umbraco.Web.Routing get { return this.Template != null ; } } + /// + /// Gets or sets the alternate template alias. + /// + /// + /// When null or empty, use the default template. + /// Alternate template works only when displaying the intended document and should be set + /// after PublishedContent since setting PublishedContent clears the alternate template. + /// + public string AlternateTemplateAlias { get; set; } + /// /// Gets the identifier of the requested content. /// diff --git a/src/Umbraco.Web/Routing/PublishedContentRequestBuilder.cs b/src/Umbraco.Web/Routing/PublishedContentRequestBuilder.cs index 41c82010b1..d419191f5b 100644 --- a/src/Umbraco.Web/Routing/PublishedContentRequestBuilder.cs +++ b/src/Umbraco.Web/Routing/PublishedContentRequestBuilder.cs @@ -197,6 +197,12 @@ namespace Umbraco.Web.Routing { const string tracePrefix = "LookupDocument2: "; + // at that point if we have a .PublishedContent then it is the "expected" document + // time to read the alternate template alias, from querystring, form, cookie or server vars. + // it will be cleared as soon as .PublishedContent change, because then it's not the + // expected content anymore and the alternate template does not apply. + _publishedContentRequest.AlternateTemplateAlias = _umbracoContext.HttpContext.Request["altTemplate"]; + // handle "not found", follow internal redirects, validate access, template // because these might loop, we have to have some sort of infinite loop detection int i = 0, j = 0; @@ -377,46 +383,70 @@ namespace Umbraco.Web.Routing // HERE we should let people register their own way of finding a template, same as with documents!!!! // do we? - //return if the request already has a template assigned, this can be possible if an ILookup assigns one - if (_publishedContentRequest.HasTemplate) return; - const string tracePrefix = "LookupTemplate: "; if (_publishedContentRequest.PublishedContent == null) throw new InvalidOperationException("There is no node."); - //gets item from query string, form, cookie or server vars - var templateAlias = _umbracoContext.HttpContext.Request["altTemplate"]; - - if (templateAlias.IsNullOrWhiteSpace()) + if (_publishedContentRequest.AlternateTemplateAlias.IsNullOrWhiteSpace()) { - //we don't have an alt template specified, so lookup the template id on the document and then lookup the template - // associated with it. - //TODO: When we remove the need for a database for templates, then this id should be irrelavent, not sure how were going to do this nicely. + // we don't have an alternate template specified. use the current one if there's one already, + // which can happen if a content lookup also set the template (LookupByNiceUrlAndTemplate...), + // else lookup the template id on the document then lookup the template with that id. + + if (_publishedContentRequest.HasTemplate) + { + LogHelper.Debug("{0}Has a template already, and no alternate template.", () => tracePrefix); + return; + } + + // TODO: When we remove the need for a database for templates, then this id should be irrelavent, + // not sure how were going to do this nicely. var templateId = _publishedContentRequest.PublishedContent.TemplateId; - LogHelper.Debug("{0}Look for template id={1}", () => tracePrefix, () => templateId); - + if (templateId > 0) - { - //NOTE: don't use the Template ctor as the result is not cached... instead use this static method + { + LogHelper.Debug("{0}Look for template id={1}", () => tracePrefix, () => templateId); + // don't use the Template ctor as the result is not cached... instead use this static method var template = Template.GetTemplate(templateId); if (template == null) throw new InvalidOperationException("The template with Id " + templateId + " does not exist, the page cannot render"); _publishedContentRequest.Template = template; + LogHelper.Debug("{0}Got template id={1} alias=\"{2}\"", () => tracePrefix, () => template.Id, () => template.Alias); + } + else + { + LogHelper.Debug("{0}No specified template.", () => tracePrefix); } } else { - LogHelper.Debug("{0}Look for template alias=\"{1}\" (altTemplate)", () => tracePrefix, () => templateAlias); + // we have an alternate template specified. lookup the template with that alias + // this means the we override any template that a content lookup might have set + // so /path/to/page/template1?altTemplate=template2 will use template2 - var template = Template.GetByAlias(templateAlias, true); - _publishedContentRequest.Template = template; + // ignore if the alias does not match - just trace + + if (_publishedContentRequest.HasTemplate) + LogHelper.Debug("{0}Has a template already, but also an alternate template.", () => tracePrefix); + LogHelper.Debug("{0}Look for alternate template alias=\"{1}\"", () => tracePrefix, () => _publishedContentRequest.AlternateTemplateAlias); + + var template = Template.GetByAlias(_publishedContentRequest.AlternateTemplateAlias, true); + if (template != null) + { + _publishedContentRequest.Template = template; + LogHelper.Debug("{0}Got template id={1} alias=\"{2}\"", () => tracePrefix, () => template.Id, () => template.Alias); + } + else + { + LogHelper.Debug("{0}The template with alias=\"{1}\" does not exist, ignoring.", () => tracePrefix, () => _publishedContentRequest.AlternateTemplateAlias); + } } if (!_publishedContentRequest.HasTemplate) { - LogHelper.Debug("{0}No template was found."); + LogHelper.Debug("{0}No template was found.", () => tracePrefix); // initial idea was: if we're not already 404 and UmbracoSettings.HandleMissingTemplateAs404 is true // then reset _publishedContentRequest.Document to null to force a 404. @@ -427,6 +457,10 @@ namespace Umbraco.Web.Routing // // so, don't set _publishedContentRequest.Document to null here } + else + { + LogHelper.Debug("{0}Running with template id={1} alias=\"{2}\"", () => tracePrefix, () => _publishedContentRequest.Template.Id, () => _publishedContentRequest.Template.Alias); + } } ///