diff --git a/src/Umbraco.Core/Models/Content.cs b/src/Umbraco.Core/Models/Content.cs index 3f6e387dec..0c679e5e70 100644 --- a/src/Umbraco.Core/Models/Content.cs +++ b/src/Umbraco.Core/Models/Content.cs @@ -16,7 +16,7 @@ namespace Umbraco.Core.Models public class Content : ContentBase, IContent { private IContentType _contentType; - private ITemplate _template; + private int? _templateId; private ContentScheduleCollection _schedule; private bool _published; private PublishedState _publishedState; @@ -83,7 +83,7 @@ namespace Umbraco.Core.Models // ReSharper disable once ClassNeverInstantiated.Local private class PropertySelectors { - public readonly PropertyInfo TemplateSelector = ExpressionHelper.GetPropertyInfo(x => x.Template); + public readonly PropertyInfo TemplateSelector = ExpressionHelper.GetPropertyInfo(x => x.TemplateId); public readonly PropertyInfo PublishedSelector = ExpressionHelper.GetPropertyInfo(x => x.Published); public readonly PropertyInfo ContentScheduleSelector = ExpressionHelper.GetPropertyInfo(x => x.ContentSchedule); public readonly PropertyInfo PublishCultureInfosSelector = ExpressionHelper.GetPropertyInfo>(x => x.PublishCultureInfos); @@ -131,10 +131,10 @@ namespace Umbraco.Core.Models /// the Default template from the ContentType will be returned. /// [DataMember] - public ITemplate Template + public int? TemplateId { - get => _template ?? _contentType.DefaultTemplate; - set => SetPropertyValueAndDetectChanges(value, ref _template, Ps.Value.TemplateSelector); + get => _templateId; + set => SetPropertyValueAndDetectChanges(value, ref _templateId, Ps.Value.TemplateSelector); } @@ -193,7 +193,7 @@ namespace Umbraco.Core.Models /// [IgnoreDataMember] - public ITemplate PublishTemplate { get; internal set; } // set by persistence + public int? PublishTemplateId { get; internal set; } // set by persistence /// [IgnoreDataMember] @@ -457,9 +457,7 @@ namespace Umbraco.Core.Models public override void ResetDirtyProperties(bool rememberDirty) { base.ResetDirtyProperties(rememberDirty); - - if (Template != null) - Template.ResetDirtyProperties(rememberDirty); + if (ContentType != null) ContentType.ResetDirtyProperties(rememberDirty); diff --git a/src/Umbraco.Core/Models/IContent.cs b/src/Umbraco.Core/Models/IContent.cs index a414a03d2f..056602f007 100644 --- a/src/Umbraco.Core/Models/IContent.cs +++ b/src/Umbraco.Core/Models/IContent.cs @@ -18,9 +18,9 @@ namespace Umbraco.Core.Models ContentScheduleCollection ContentSchedule { get; set; } /// - /// Gets or sets the template used to render the content. + /// Gets or sets the template id used to render the content. /// - ITemplate Template { get; set; } + int? TemplateId { get; set; } /// /// Gets a value indicating whether the content is published. @@ -45,10 +45,10 @@ namespace Umbraco.Core.Models bool Blueprint { get; } /// - /// Gets the template used to render the published version of the content. + /// Gets the template id used to render the published version of the content. /// /// When editing the content, the template can change, but this will not until the content is published. - ITemplate PublishTemplate { get; } + int? PublishTemplateId { get; } /// /// Gets the name of the published version of the content. diff --git a/src/Umbraco.Core/Models/PublishedContent/IPublishedContent.cs b/src/Umbraco.Core/Models/PublishedContent/IPublishedContent.cs index 0c049e81bf..4e1ce7ddd7 100644 --- a/src/Umbraco.Core/Models/PublishedContent/IPublishedContent.cs +++ b/src/Umbraco.Core/Models/PublishedContent/IPublishedContent.cs @@ -62,7 +62,7 @@ namespace Umbraco.Core.Models.PublishedContent /// /// Gets the identifier of the template to use to render the content item. /// - int TemplateId { get; } + int? TemplateId { get; } /// /// Gets the identifier of the user who created the content item. diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedContentWrapped.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedContentWrapped.cs index 6a69d0b9e1..36755c8944 100644 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedContentWrapped.cs +++ b/src/Umbraco.Core/Models/PublishedContent/PublishedContentWrapped.cs @@ -73,7 +73,7 @@ namespace Umbraco.Core.Models.PublishedContent public virtual string Path => _content.Path; /// - public virtual int TemplateId => _content.TemplateId; + public virtual int? TemplateId => _content.TemplateId; /// public virtual int CreatorId => _content.CreatorId; diff --git a/src/Umbraco.Core/Persistence/Factories/ContentBaseFactory.cs b/src/Umbraco.Core/Persistence/Factories/ContentBaseFactory.cs index c8467f47e2..7fe1d44921 100644 --- a/src/Umbraco.Core/Persistence/Factories/ContentBaseFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/ContentBaseFactory.cs @@ -282,7 +282,7 @@ namespace Umbraco.Core.Persistence.Factories var dto = new DocumentVersionDto { Id = entity.VersionId, - TemplateId = entity.Template?.Id, + TemplateId = entity.TemplateId, Published = false, // always building the current, unpublished one ContentVersionDto = BuildContentVersionDto(entity, contentDto) diff --git a/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs index 1f24c7c414..40ce07f193 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Implement/DocumentRepository.cs @@ -273,8 +273,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement var publishing = content.PublishedState == PublishedState.Publishing; // ensure that the default template is assigned - if (entity.Template == null) - entity.Template = entity.ContentType.DefaultTemplate; + if (entity.TemplateId.HasValue == false) + entity.TemplateId = entity.ContentType.DefaultTemplate?.Id; // sanitize names SanitizeNames(content, publishing); @@ -404,7 +404,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement if (content.PublishedState == PublishedState.Publishing) { content.Published = true; - content.PublishTemplate = content.Template; + content.PublishTemplateId = content.TemplateId; content.PublisherId = content.WriterId; content.PublishName = content.Name; content.PublishDate = content.UpdateDate; @@ -414,7 +414,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement else if (content.PublishedState == PublishedState.Unpublishing) { content.Published = false; - content.PublishTemplate = null; + content.PublishTemplateId = null; content.PublisherId = null; content.PublishName = null; content.PublishDate = null; @@ -609,7 +609,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement if (content.PublishedState == PublishedState.Publishing) { content.Published = true; - content.PublishTemplate = content.Template; + content.PublishTemplateId = content.TemplateId; content.PublisherId = content.WriterId; content.PublishName = content.Name; content.PublishDate = content.UpdateDate; @@ -619,7 +619,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement else if (content.PublishedState == PublishedState.Unpublishing) { content.Published = false; - content.PublishTemplate = null; + content.PublishTemplateId = null; content.PublisherId = null; content.PublishName = null; content.PublishDate = null; @@ -1079,10 +1079,11 @@ namespace Umbraco.Core.Persistence.Repositories.Implement foreach (var temp in temps) { // complete the item - if (temp.Template1Id.HasValue && templates.TryGetValue(temp.Template1Id.Value, out var template)) - temp.Content.Template = template; - if (temp.Template2Id.HasValue && templates.TryGetValue(temp.Template2Id.Value, out template)) - temp.Content.PublishTemplate = template; + // fixme - this makes no sense, no need to manage templates on TEMP anymore?! + if (temp.Template1Id.HasValue && templates.ContainsKey(temp.Template1Id.Value)) + temp.Content.TemplateId = temp.Template1Id; + if (temp.Template2Id.HasValue && templates.ContainsKey(temp.Template2Id.Value)) + temp.Content.PublishTemplateId = temp.Template2Id; if (properties.ContainsKey(temp.VersionId)) temp.Content.Properties = properties[temp.VersionId]; @@ -1123,7 +1124,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement // get template if (dto.DocumentVersionDto.TemplateId.HasValue && dto.DocumentVersionDto.TemplateId.Value > 0) - content.Template = _templateRepository.Get(dto.DocumentVersionDto.TemplateId.Value); + content.TemplateId = dto.DocumentVersionDto.TemplateId; // get properties - indexed by version id var versionId = dto.DocumentVersionDto.Id; diff --git a/src/Umbraco.Core/Services/EntityXmlSerializer.cs b/src/Umbraco.Core/Services/EntityXmlSerializer.cs index 5b64584dc6..d938e032a8 100644 --- a/src/Umbraco.Core/Services/EntityXmlSerializer.cs +++ b/src/Umbraco.Core/Services/EntityXmlSerializer.cs @@ -52,7 +52,7 @@ namespace Umbraco.Core.Services xml.Add(new XAttribute("writerName", content.GetWriterProfile(userService)?.Name ?? "??")); xml.Add(new XAttribute("writerID", content.WriterId)); - xml.Add(new XAttribute("template", content.Template?.Id.ToString(CultureInfo.InvariantCulture) ?? "0")); + xml.Add(new XAttribute("template", content.TemplateId?.ToString(CultureInfo.InvariantCulture) ?? "")); xml.Add(new XAttribute("isPublished", content.Published)); diff --git a/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs b/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs index 5237b92ab8..203350203d 100644 --- a/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs +++ b/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs @@ -206,7 +206,7 @@ namespace Umbraco.Tests.Cache.PublishedCache var store = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new StaticCacheProvider(), ContentTypesCache); var doc = store.CreateFromCacheValues(store.ConvertFromSearchResult(result)); - DoAssert(doc, 1234, key, 0, 0, "/media/test.jpg", "Image", 23, "Shannon", "Shannon", 0, 0, "-1,1234", DateTime.Parse("2012-07-17T10:34:09"), DateTime.Parse("2012-07-16T10:34:09"), 2); + DoAssert(doc, 1234, key, templateIdVal: null, 0, "/media/test.jpg", "Image", 23, "Shannon", "Shannon", 0, 0, "-1,1234", DateTime.Parse("2012-07-17T10:34:09"), DateTime.Parse("2012-07-16T10:34:09"), 2); Assert.AreEqual(null, doc.Parent); } @@ -222,7 +222,7 @@ namespace Umbraco.Tests.Cache.PublishedCache var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null), ServiceContext.MediaService, ServiceContext.UserService, new StaticCacheProvider(), ContentTypesCache); var doc = cache.CreateFromCacheValues(cache.ConvertFromXPathNavigator(navigator, true)); - DoAssert(doc, 2000, key, 0, 2, "image1", "Image", 23, "Shannon", "Shannon", 33, 33, "-1,2000", DateTime.Parse("2012-06-12T14:13:17"), DateTime.Parse("2012-07-20T18:50:43"), 1); + DoAssert(doc, 2000, key, templateIdVal: null, 2, "image1", "Image", 23, "Shannon", "Shannon", 33, 33, "-1,2000", DateTime.Parse("2012-06-12T14:13:17"), DateTime.Parse("2012-07-20T18:50:43"), 1); Assert.AreEqual(null, doc.Parent); Assert.AreEqual(2, doc.Children.Count()); Assert.AreEqual(2001, doc.Children.ElementAt(0).Id); @@ -336,7 +336,7 @@ namespace Umbraco.Tests.Cache.PublishedCache DictionaryPublishedContent dicDoc, int idVal = 1234, Guid keyVal = default(Guid), - int templateIdVal = 0, + int? templateIdVal = null, int sortOrderVal = 44, string urlNameVal = "testing", string nodeTypeAliasVal = "myType", @@ -367,7 +367,7 @@ namespace Umbraco.Tests.Cache.PublishedCache IPublishedContent doc, int idVal = 1234, Guid keyVal = default(Guid), - int templateIdVal = 0, + int? templateIdVal = null, int sortOrderVal = 44, string urlNameVal = "testing", string nodeTypeAliasVal = "myType", @@ -401,9 +401,6 @@ namespace Umbraco.Tests.Cache.PublishedCache Assert.AreEqual(createDateVal.Value, doc.CreateDate); Assert.AreEqual(updateDateVal.Value, doc.UpdateDate); Assert.AreEqual(levelVal, doc.Level); - } - - } } diff --git a/src/Umbraco.Tests/Models/ContentTests.cs b/src/Umbraco.Tests/Models/ContentTests.cs index 24aeb1668f..ea5614fb85 100644 --- a/src/Umbraco.Tests/Models/ContentTests.cs +++ b/src/Umbraco.Tests/Models/ContentTests.cs @@ -227,10 +227,7 @@ namespace Umbraco.Tests.Models content.ContentSchedule.Add(DateTime.Now, DateTime.Now.AddDays(1)); //content.ChangePublishedState(PublishedState.Published); content.SortOrder = 5; - content.Template = new Template((string) "Test Template", (string) "testTemplate") - { - Id = 88 - }; + content.TemplateId = 88; content.Trashed = false; content.UpdateDate = DateTime.Now; content.WriterId = 23; @@ -289,10 +286,7 @@ namespace Umbraco.Tests.Models content.Path = "-1,4,10"; content.ContentSchedule.Add(DateTime.Now, DateTime.Now.AddDays(1)); content.SortOrder = 5; - content.Template = new Template((string) "Test Template", (string) "testTemplate") - { - Id = 88 - }; + content.TemplateId = 88; content.Trashed = false; content.UpdateDate = DateTime.Now; content.WriterId = 23; @@ -332,8 +326,8 @@ namespace Umbraco.Tests.Models Assert.AreEqual(clone.PublishedState, content.PublishedState); Assert.AreEqual(clone.SortOrder, content.SortOrder); Assert.AreEqual(clone.PublishedState, content.PublishedState); - Assert.AreNotSame(clone.Template, content.Template); - Assert.AreEqual(clone.Template, content.Template); + Assert.AreNotSame(clone.TemplateId, content.TemplateId); + Assert.AreEqual(clone.TemplateId, content.TemplateId); Assert.AreEqual(clone.Trashed, content.Trashed); Assert.AreEqual(clone.UpdateDate, content.UpdateDate); Assert.AreEqual(clone.VersionId, content.VersionId); @@ -408,16 +402,12 @@ namespace Umbraco.Tests.Models content.Level = 3; content.Path = "-1,4,10"; content.SortOrder = 5; - content.Template = new Template((string)"Test Template", (string)"testTemplate") - { - Id = 88 - }; + content.TemplateId = 88; content.Trashed = true; content.UpdateDate = DateTime.Now; content.WriterId = 23; - - content.Template.UpdateDate = DateTime.Now; //update a child object + content.ContentType.UpdateDate = DateTime.Now; //update a child object // Act @@ -425,18 +415,18 @@ namespace Umbraco.Tests.Models // Assert Assert.IsTrue(content.WasDirty()); - Assert.IsTrue(content.WasPropertyDirty("Id")); - Assert.IsTrue(content.WasPropertyDirty("CreateDate")); - Assert.IsTrue(content.WasPropertyDirty("CreatorId")); - Assert.IsTrue(content.WasPropertyDirty("Key")); - Assert.IsTrue(content.WasPropertyDirty("Level")); - Assert.IsTrue(content.WasPropertyDirty("Path")); - Assert.IsTrue(content.WasPropertyDirty("ContentSchedule")); - Assert.IsTrue(content.WasPropertyDirty("SortOrder")); - Assert.IsTrue(content.WasPropertyDirty("Template")); - Assert.IsTrue(content.WasPropertyDirty("Trashed")); - Assert.IsTrue(content.WasPropertyDirty("UpdateDate")); - Assert.IsTrue(content.WasPropertyDirty("WriterId")); + Assert.IsTrue(content.WasPropertyDirty(nameof(Content.Id))); + Assert.IsTrue(content.WasPropertyDirty(nameof(Content.CreateDate))); + Assert.IsTrue(content.WasPropertyDirty(nameof(Content.CreatorId))); + Assert.IsTrue(content.WasPropertyDirty(nameof(Content.Key))); + Assert.IsTrue(content.WasPropertyDirty(nameof(Content.Level))); + Assert.IsTrue(content.WasPropertyDirty(nameof(Content.Path))); + Assert.IsTrue(content.WasPropertyDirty(nameof(Content.ContentSchedule))); + Assert.IsTrue(content.WasPropertyDirty(nameof(Content.SortOrder))); + Assert.IsTrue(content.WasPropertyDirty(nameof(Content.TemplateId))); + Assert.IsTrue(content.WasPropertyDirty(nameof(Content.Trashed))); + Assert.IsTrue(content.WasPropertyDirty(nameof(Content.UpdateDate))); + Assert.IsTrue(content.WasPropertyDirty(nameof(Content.WriterId))); foreach (var prop in content.Properties) { Assert.IsTrue(prop.WasDirty()); @@ -457,7 +447,6 @@ namespace Umbraco.Tests.Models Assert.IsTrue(culture.Value.WasPropertyDirty("Date")); } //verify child objects were reset too - Assert.IsTrue(content.Template.WasPropertyDirty("UpdateDate")); Assert.IsTrue(content.ContentType.WasPropertyDirty("UpdateDate")); } @@ -484,10 +473,7 @@ namespace Umbraco.Tests.Models content.ContentSchedule.Add(DateTime.Now, DateTime.Now.AddDays(1)); //content.ChangePublishedState(PublishedState.Publishing); content.SortOrder = 5; - content.Template = new Template((string) "Test Template", (string) "testTemplate") - { - Id = 88 - }; + content.TemplateId = 88; content.Trashed = false; content.UpdateDate = DateTime.Now; content.WriterId = 23; diff --git a/src/Umbraco.Tests/Models/ContentXmlTest.cs b/src/Umbraco.Tests/Models/ContentXmlTest.cs index ab318ec1cb..a6a5e3a9ef 100644 --- a/src/Umbraco.Tests/Models/ContentXmlTest.cs +++ b/src/Umbraco.Tests/Models/ContentXmlTest.cs @@ -49,7 +49,7 @@ namespace Umbraco.Tests.Models Assert.AreEqual(content.GetCreatorProfile(ServiceContext.UserService).Name, (string)element.Attribute("creatorName")); Assert.AreEqual(content.GetWriterProfile(ServiceContext.UserService).Name, (string)element.Attribute("writerName")); Assert.AreEqual(content.WriterId.ToString(), (string)element.Attribute("writerID")); - Assert.AreEqual(content.Template == null ? "0" : content.Template.Id.ToString(), (string)element.Attribute("template")); + Assert.AreEqual(content.TemplateId.ToString(), (string)element.Attribute("template")); Assert.AreEqual(content.Properties["title"].GetValue().ToString(), element.Elements("title").Single().Value); Assert.AreEqual(content.Properties["bodyText"].GetValue().ToString(), element.Elements("bodyText").Single().Value); diff --git a/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs index 1f0036d874..c1fa5381ff 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/DocumentRepositoryTest.cs @@ -432,8 +432,9 @@ namespace Umbraco.Tests.Persistence.Repositories var fetched = repository.Get(textpage.Id); - Assert.NotNull(textpage.Template); - Assert.AreEqual(textpage.Template, contentType.DefaultTemplate); + Assert.True(textpage.TemplateId.HasValue); + Assert.NotZero(textpage.TemplateId.Value); + Assert.AreEqual(textpage.TemplateId, contentType.DefaultTemplate.Id); scope.Complete(); @@ -557,12 +558,12 @@ namespace Umbraco.Tests.Persistence.Repositories var repository = CreateRepository((IScopeAccessor)provider, out _); var content = repository.Get(NodeDto.NodeIdSeed + 2); - content.Template = null; + content.TemplateId = null; repository.Save(content); var updatedContent = repository.Get(NodeDto.NodeIdSeed + 2); - Assert.IsNull(updatedContent.Template); + Assert.False(updatedContent.TemplateId.HasValue); } } diff --git a/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs index 3ec9d572bf..f4bed68315 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/TemplateRepositoryTest.cs @@ -380,7 +380,7 @@ namespace Umbraco.Tests.Persistence.Repositories }; templateRepository.Save(template); - textpage.Template = template; + textpage.TemplateId = template.Id; contentRepo.Save(textpage); // Act diff --git a/src/Umbraco.Tests/Published/NestedContentTests.cs b/src/Umbraco.Tests/Published/NestedContentTests.cs index cf00345b65..fc1b4d8f3c 100644 --- a/src/Umbraco.Tests/Published/NestedContentTests.cs +++ b/src/Umbraco.Tests/Published/NestedContentTests.cs @@ -270,7 +270,7 @@ namespace Umbraco.Tests.Published // ReSharper disable UnassignedGetOnlyAutoProperty public override int Id { get; } - public override int TemplateId { get; } + public override int? TemplateId { get; } public override int SortOrder { get; } public override string Name { get; } public override PublishedCultureInfo GetCulture(string culture = ".") => throw new NotSupportedException(); diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs index aa9e7e4918..3af930c4c3 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentDataTableTests.cs @@ -201,7 +201,7 @@ namespace Umbraco.Tests.PublishedContent public IPublishedContent Parent { get; set; } public int Id { get; set; } public Guid Key { get; set; } - public int TemplateId { get; set; } + public int? TemplateId { get; set; } public int SortOrder { get; set; } public string Name { get; set; } public PublishedCultureInfo GetCulture(string culture = null) => throw new NotSupportedException(); diff --git a/src/Umbraco.Tests/PublishedContent/SolidPublishedSnapshot.cs b/src/Umbraco.Tests/PublishedContent/SolidPublishedSnapshot.cs index 0c4059ca7c..deaecf821e 100644 --- a/src/Umbraco.Tests/PublishedContent/SolidPublishedSnapshot.cs +++ b/src/Umbraco.Tests/PublishedContent/SolidPublishedSnapshot.cs @@ -172,7 +172,7 @@ namespace Umbraco.Tests.PublishedContent public int Id { get; set; } public Guid Key { get; set; } - public int TemplateId { get; set; } + public int? TemplateId { get; set; } public int SortOrder { get; set; } public string Name { get; set; } public PublishedCultureInfo GetCulture(string culture = null) => throw new NotSupportedException(); diff --git a/src/Umbraco.Tests/TestHelpers/Stubs/TestPublishedContent.cs b/src/Umbraco.Tests/TestHelpers/Stubs/TestPublishedContent.cs index 9c0bb61cb3..58c8e37cbf 100644 --- a/src/Umbraco.Tests/TestHelpers/Stubs/TestPublishedContent.cs +++ b/src/Umbraco.Tests/TestHelpers/Stubs/TestPublishedContent.cs @@ -15,7 +15,7 @@ namespace Umbraco.Tests.TestHelpers.Stubs } public int Id { get; } - public int TemplateId { get; set; } + public int? TemplateId { get; set; } public int SortOrder { get; set; } public string Name { get; set; } public IVariationContextAccessor VariationContextAccessor { get; set; } diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs index 80ba00d07a..46a053bb77 100644 --- a/src/Umbraco.Web/Editors/ContentController.cs +++ b/src/Umbraco.Web/Editors/ContentController.cs @@ -1780,22 +1780,24 @@ namespace Umbraco.Web.Editors variantIndex++; } - //only set the template if it didn't change - var templateChanged = (contentSave.PersistedContent.Template == null && contentSave.TemplateAlias.IsNullOrWhiteSpace() == false) - || (contentSave.PersistedContent.Template != null && contentSave.PersistedContent.Template.Alias != contentSave.TemplateAlias) - || (contentSave.PersistedContent.Template != null && contentSave.TemplateAlias.IsNullOrWhiteSpace()); - if (templateChanged) + // If the template was set. + // fixme review this - what if template has been cleared? + if (contentSave.TemplateAlias != null) { + //only set the template if it didn't change var template = Services.FileService.GetTemplate(contentSave.TemplateAlias); - if (template == null && contentSave.TemplateAlias.IsNullOrWhiteSpace() == false) + if (contentSave.PersistedContent.TemplateId != template.Id) { - //ModelState.AddModelError("Template", "No template exists with the specified alias: " + contentItem.TemplateAlias); - Logger.Warn("No template exists with the specified alias: {TemplateAlias}", contentSave.TemplateAlias); - } - else - { - //NOTE: this could be null if there was a template and the posted template is null, this should remove the assigned template - contentSave.PersistedContent.Template = template; + if (template == null && contentSave.TemplateAlias.IsNullOrWhiteSpace() == false) + { + //ModelState.AddModelError("Template", "No template exists with the specified alias: " + contentItem.TemplateAlias); + Logger.Warn("No template exists with the specified alias: {TemplateAlias}", contentSave.TemplateAlias); + } + else + { + //NOTE: this could be null if there was a template and the posted template is null, this should remove the assigned template + contentSave.PersistedContent.TemplateId = template.Id; + } } } } diff --git a/src/Umbraco.Web/Models/Mapping/DefaultTemplateResolver.cs b/src/Umbraco.Web/Models/Mapping/DefaultTemplateResolver.cs index ae32e7a691..12caf93681 100644 --- a/src/Umbraco.Web/Models/Mapping/DefaultTemplateResolver.cs +++ b/src/Umbraco.Web/Models/Mapping/DefaultTemplateResolver.cs @@ -1,5 +1,7 @@ using AutoMapper; +using System.Web.Mvc; using Umbraco.Core.Models; +using Umbraco.Core.Services; using Umbraco.Web.Models.ContentEditing; namespace Umbraco.Web.Models.Mapping @@ -8,17 +10,24 @@ namespace Umbraco.Web.Models.Mapping { public string Resolve(IContent source, ContentItemDisplay destination, string destMember, ResolutionContext context) { - if (source == null || source.Template == null) return null; + if (source == null) + return null; - var alias = source.Template.Alias; + // If no template id was set... + if (!source.TemplateId.HasValue) + { + // ... and no default template is set, return null... + if (string.IsNullOrWhiteSpace(source.ContentType.DefaultTemplate?.Alias)) + return null; - //set default template if template isn't set - if (string.IsNullOrEmpty(alias)) - alias = source.ContentType.DefaultTemplate == null - ? string.Empty - : source.ContentType.DefaultTemplate.Alias; + // ... otherwise return the content type default template alias. + return source.ContentType.DefaultTemplate?.Alias; + } + + var fileService = DependencyResolver.Current.GetService(); + var template = fileService.GetTemplate(source.TemplateId.Value); - return alias; + return template.Alias; } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Web/Models/PublishedContentBase.cs b/src/Umbraco.Web/Models/PublishedContentBase.cs index 667cf145bd..2d00370f14 100644 --- a/src/Umbraco.Web/Models/PublishedContentBase.cs +++ b/src/Umbraco.Web/Models/PublishedContentBase.cs @@ -51,7 +51,7 @@ namespace Umbraco.Web.Models public abstract string Path { get; } /// - public abstract int TemplateId { get; } + public abstract int? TemplateId { get; } /// public abstract int CreatorId { get; } diff --git a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/BTree.ContentDataSerializer.cs b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/BTree.ContentDataSerializer.cs index 7c793b69bd..80633efe2e 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/BTree.ContentDataSerializer.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/BTree.ContentDataSerializer.cs @@ -30,9 +30,12 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource PrimitiveSerializer.Int32.WriteTo(value.VersionId, stream); PrimitiveSerializer.DateTime.WriteTo(value.VersionDate, stream); PrimitiveSerializer.Int32.WriteTo(value.WriterId, stream); - PrimitiveSerializer.Int32.WriteTo(value.TemplateId, stream); + if (value.TemplateId.HasValue) + { + PrimitiveSerializer.Int32.WriteTo(value.TemplateId.Value, stream); + } PropertiesSerializer.WriteTo(value.Properties, stream); CultureVariationsSerializer.WriteTo(value.CultureInfos, stream); } } -} \ No newline at end of file +} diff --git a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/ContentData.cs b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/ContentData.cs index 4721a1f4ca..520cc99011 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/DataSource/ContentData.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/DataSource/ContentData.cs @@ -10,7 +10,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource public int VersionId { get; set; } public DateTime VersionDate { get; set; } public int WriterId { get; set; } - public int TemplateId { get; set; } + public int? TemplateId { get; set; } public bool Published { get; set; } public IDictionary Properties { get; set; } diff --git a/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs b/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs index 36e5698e32..25e5244d32 100644 --- a/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs +++ b/src/Umbraco.Web/PublishedCache/NuCache/PublishedContent.cs @@ -215,7 +215,7 @@ namespace Umbraco.Web.PublishedCache.NuCache public override string Path => _contentNode.Path; /// - public override int TemplateId => _contentData.TemplateId; + public override int? TemplateId => _contentData.TemplateId; /// public override int CreatorId => _contentNode.CreatorId; diff --git a/src/Umbraco.Web/PublishedCache/PublishedMember.cs b/src/Umbraco.Web/PublishedCache/PublishedMember.cs index 56c8f440d8..46abc098cc 100644 --- a/src/Umbraco.Web/PublishedCache/PublishedMember.cs +++ b/src/Umbraco.Web/PublishedCache/PublishedMember.cs @@ -129,7 +129,7 @@ namespace Umbraco.Web.PublishedCache public override Guid Key => _member.Key; - public override int TemplateId => throw new NotSupportedException(); + public override int? TemplateId => throw new NotSupportedException(); public override int SortOrder => 0; diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/DictionaryPublishedContent.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/DictionaryPublishedContent.cs index 7c311236c0..a845be286f 100644 --- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/DictionaryPublishedContent.cs +++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/DictionaryPublishedContent.cs @@ -148,7 +148,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache public override Guid Key => _key; - public override int TemplateId => 0; + public override int? TemplateId => null; public override int SortOrder => _sortOrder; diff --git a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlPublishedContent.cs b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlPublishedContent.cs index af867cc089..efd4535bd4 100644 --- a/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlPublishedContent.cs +++ b/src/Umbraco.Web/PublishedCache/XmlPublishedCache/XmlPublishedContent.cs @@ -109,7 +109,7 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache } } - public override int TemplateId + public override int? TemplateId { get { diff --git a/src/Umbraco.Web/PublishedContentExtensions.cs b/src/Umbraco.Web/PublishedContentExtensions.cs index 3780586797..d4494c5f91 100644 --- a/src/Umbraco.Web/PublishedContentExtensions.cs +++ b/src/Umbraco.Web/PublishedContentExtensions.cs @@ -133,10 +133,15 @@ namespace Umbraco.Web /// Returns the current template Alias /// /// - /// + /// Empty string if none is set. public static string GetTemplateAlias(this IPublishedContent content) { - var template = Current.Services.FileService.GetTemplate(content.TemplateId); + if(content.TemplateId.HasValue == false) + { + return string.Empty; + } + + var template = Current.Services.FileService.GetTemplate(content.TemplateId.Value); return template == null ? string.Empty : template.Alias; } diff --git a/src/Umbraco.Web/Routing/PublishedRouter.cs b/src/Umbraco.Web/Routing/PublishedRouter.cs index 1ff33e42bc..3d3b623838 100644 --- a/src/Umbraco.Web/Routing/PublishedRouter.cs +++ b/src/Umbraco.Web/Routing/PublishedRouter.cs @@ -755,9 +755,9 @@ namespace Umbraco.Web.Routing } } - private ITemplate GetTemplateModel(int templateId) + private ITemplate GetTemplateModel(int? templateId) { - if (templateId <= 0) + if (templateId.HasValue == false) { _logger.Debug("GetTemplateModel: No template."); return null; @@ -765,7 +765,10 @@ namespace Umbraco.Web.Routing _logger.Debug("GetTemplateModel: Get template id={TemplateId}", templateId); - var template = _services.FileService.GetTemplate(templateId); + if (templateId == null) + throw new InvalidOperationException("The template is not set, the page cannot render."); + + var template = _services.FileService.GetTemplate(templateId.Value); if (template == null) throw new InvalidOperationException("The template with Id " + templateId + " does not exist, the page cannot render."); _logger.Debug("GetTemplateModel: Got template id={TemplateId} alias={TemplateAlias}", template.Id, template.Alias); diff --git a/src/Umbraco.Web/Templates/TemplateRenderer.cs b/src/Umbraco.Web/Templates/TemplateRenderer.cs index 7281874dd2..a339f45714 100644 --- a/src/Umbraco.Web/Templates/TemplateRenderer.cs +++ b/src/Umbraco.Web/Templates/TemplateRenderer.cs @@ -33,7 +33,7 @@ namespace Umbraco.Web.Templates public TemplateRenderer(UmbracoContext umbracoContext, int pageId, int? altTemplateId) { PageId = pageId; - AltTemplate = altTemplateId; + AltTemplateId = altTemplateId; _umbracoContext = umbracoContext ?? throw new ArgumentNullException(nameof(umbracoContext)); } @@ -49,7 +49,7 @@ namespace Umbraco.Web.Templates /// /// Gets/sets the alt template to render if there is one /// - public int? AltTemplate { get; } + public int? AltTemplateId { get; } public void Render(StringWriter writer) { @@ -86,20 +86,22 @@ namespace Umbraco.Web.Templates //set the doc that was found by id contentRequest.PublishedContent = doc; //set the template, either based on the AltTemplate found or the standard template of the doc - contentRequest.TemplateModel = Current.Configs.Settings().WebRouting.DisableAlternativeTemplates || AltTemplate.HasValue == false - ? FileService.GetTemplate(doc.TemplateId) - : FileService.GetTemplate(AltTemplate.Value); + var templateId = Current.Configs.Settings().WebRouting.DisableAlternativeTemplates || !AltTemplateId.HasValue + ? doc.TemplateId + : AltTemplateId.Value; + if (templateId.HasValue) + contentRequest.TemplateModel = FileService.GetTemplate(templateId.Value); //if there is not template then exit if (contentRequest.HasTemplate == false) { - if (AltTemplate.HasValue == false) + if (AltTemplateId.HasValue == false) { writer.Write("", doc.TemplateId); } else { - writer.Write("", AltTemplate); + writer.Write("", AltTemplateId); } return; } diff --git a/src/Umbraco.Web/umbraco.presentation/page.cs b/src/Umbraco.Web/umbraco.presentation/page.cs index 219e2101be..e3fdf8331f 100644 --- a/src/Umbraco.Web/umbraco.presentation/page.cs +++ b/src/Umbraco.Web/umbraco.presentation/page.cs @@ -88,10 +88,10 @@ namespace umbraco doc.WriterName, doc.CreatorName, doc.CreateDate, doc.UpdateDate, doc.Path, doc.Parent == null ? -1 : doc.Parent.Id); - if (doc.TemplateId > 0) + if (doc.TemplateId.HasValue) { //set the template to whatever is assigned to the doc - _template = doc.TemplateId; + _template = doc.TemplateId.Value; _elements["template"] = _template.ToString(); } @@ -357,10 +357,7 @@ namespace umbraco get { return _key; } } - public int TemplateId - { - get { return _inner.Template == null ? 0 : _inner.Template.Id; } - } + public int? TemplateId => _inner.TemplateId; public int SortOrder {