diff --git a/src/Kentico.Xperience.TagManager/Admin/CodeSnippetConfigurationModel.cs b/src/Kentico.Xperience.TagManager/Admin/CodeSnippetConfigurationModel.cs index 22223eb..f793b8e 100644 --- a/src/Kentico.Xperience.TagManager/Admin/CodeSnippetConfigurationModel.cs +++ b/src/Kentico.Xperience.TagManager/Admin/CodeSnippetConfigurationModel.cs @@ -27,7 +27,7 @@ internal class CodeSnippetConfigurationModel [VisibleIfEqualTo(nameof(TagType), CustomSnippetFactory.TAG_TYPE_NAME)] public string? Code { get; set; } - [RadioGroupComponent(Label = "Tag location", Order = 5, Options = CodeSnippetLocationsExtensions.FormComponentOptions)] + [RadioGroupComponent(Label = "Tag location", Order = 5, Options = CodeSnippetExtensions.LocationFormComponentOptions)] [VisibleIfEqualTo(nameof(TagType), CustomSnippetFactory.TAG_TYPE_NAME)] public string? Location { get; set; } @@ -38,6 +38,9 @@ internal class CodeSnippetConfigurationModel [ObjectIdSelectorComponent(objectType: ConsentInfo.OBJECT_TYPE, Label = "Consent", Order = 6, Placeholder = "No consent needed")] public IEnumerable ConsentIDs { get; set; } = []; + [DropDownComponent(Label = "Kentico administration Display Mode", Options = CodeSnippetExtensions.DisplayModeFormComponentOptions, Order = 7)] + public string DisplayMode { get; set; } = "None"; + public void MapToChannelCodeSnippetInfo(ChannelCodeSnippetItemInfo info) { info.ChannelCodeSnippetItemChannelId = ChannelIDs.FirstOrDefault(); @@ -47,13 +50,19 @@ public void MapToChannelCodeSnippetInfo(ChannelCodeSnippetItemInfo info) info.ChannelCodeSnippetItemName = Name; info.ChannelCodeSnippetItemIdentifier = TagIdentifier; info.ChannelCodeSnippetItemCode = Code; + info.ChannelCodeSnippetAdministrationDisplayMode = DisplayMode; } } -internal static class CodeSnippetLocationsExtensions +internal static class CodeSnippetExtensions { - public const string FormComponentOptions = $"{nameof(CodeSnippetLocations.HeadTop)};Insert at the top of the head\r\n" + + public const string LocationFormComponentOptions = $"{nameof(CodeSnippetLocations.HeadTop)};Insert at the top of the head\r\n" + $"{nameof(CodeSnippetLocations.HeadBottom)};Insert at the bottom of the head\r\n" + $"{nameof(CodeSnippetLocations.BodyTop)};Insert at the top of the body\r\n" + $"{nameof(CodeSnippetLocations.BodyBottom)};Insert at the bottom of the body\r\n"; + + public const string DisplayModeFormComponentOptions = $"{nameof(CodeSnippetAdministrationDisplayMode.None)};Do not dispaly in Administration\r\n" + + $"{nameof(CodeSnippetAdministrationDisplayMode.PreviewOnly)};Display in the Preview only\r\n" + + $"{nameof(CodeSnippetAdministrationDisplayMode.PageBuilderOnly)};Display in the PageBuilder only\r\n" + + $"{nameof(CodeSnippetAdministrationDisplayMode.Both)};Display in Preview and Pagebuilder"; } diff --git a/src/Kentico.Xperience.TagManager/Admin/InfoModels/ChannelCodeSnippetItem/ChannelCodeSnippetItemInfo.generated.cs b/src/Kentico.Xperience.TagManager/Admin/InfoModels/ChannelCodeSnippetItem/ChannelCodeSnippetItemInfo.generated.cs index c6c548d..4aba8fc 100644 --- a/src/Kentico.Xperience.TagManager/Admin/InfoModels/ChannelCodeSnippetItem/ChannelCodeSnippetItemInfo.generated.cs +++ b/src/Kentico.Xperience.TagManager/Admin/InfoModels/ChannelCodeSnippetItem/ChannelCodeSnippetItemInfo.generated.cs @@ -6,6 +6,7 @@ using CMS.Helpers; using CMS.ContentEngine; using CMS.DataProtection; + using Kentico.Xperience.TagManager.Admin; [assembly: RegisterObjectType(typeof(ChannelCodeSnippetItemInfo), ChannelCodeSnippetItemInfo.OBJECT_TYPE)] @@ -120,7 +121,7 @@ public virtual string ChannelCodeSnippetItemLocation /// - /// Channel code snippet GTMID. + /// Channel code snippet third party identifier. /// [DatabaseField] public virtual string ChannelCodeSnippetItemIdentifier @@ -140,6 +141,16 @@ public virtual string ChannelCodeSnippetItemCode set => SetValue(nameof(ChannelCodeSnippetItemCode), value, String.Empty); } + /// + /// Channel code snippet administration display mode. + /// + [DatabaseField] + public virtual string ChannelCodeSnippetAdministrationDisplayMode + { + get => ValidationHelper.GetString(GetValue(nameof(ChannelCodeSnippetAdministrationDisplayMode)), String.Empty); + set => SetValue(nameof(ChannelCodeSnippetAdministrationDisplayMode), value, String.Empty); + } + /// /// Channel code snippet consent ID. diff --git a/src/Kentico.Xperience.TagManager/Admin/TagManagerModuleInstaller.cs b/src/Kentico.Xperience.TagManager/Admin/TagManagerModuleInstaller.cs index 69ac8f5..d8ad0a4 100644 --- a/src/Kentico.Xperience.TagManager/Admin/TagManagerModuleInstaller.cs +++ b/src/Kentico.Xperience.TagManager/Admin/TagManagerModuleInstaller.cs @@ -137,6 +137,18 @@ private static void InstallChannelCodeSnippetClass(ResourceInfo resourceInfo) }; formInfo.AddFormItem(formItem); + formItem = new FormFieldInfo + { + Name = nameof(ChannelCodeSnippetItemInfo.ChannelCodeSnippetAdministrationDisplayMode), + Visible = false, + Precision = 0, + Size = 200, + DataType = FieldDataType.Text, + Enabled = true, + AllowEmpty = true + }; + formInfo.AddFormItem(formItem); + formItem = new FormFieldInfo { Name = nameof(ChannelCodeSnippetItemInfo.ChannelCodeSnippetItemType), diff --git a/src/Kentico.Xperience.TagManager/Admin/UIPages/CodeSnippetEditPage.cs b/src/Kentico.Xperience.TagManager/Admin/UIPages/CodeSnippetEditPage.cs index deaa7d2..407583e 100644 --- a/src/Kentico.Xperience.TagManager/Admin/UIPages/CodeSnippetEditPage.cs +++ b/src/Kentico.Xperience.TagManager/Admin/UIPages/CodeSnippetEditPage.cs @@ -41,6 +41,7 @@ protected override CodeSnippetConfigurationModel Model ChannelIDs = [info.ChannelCodeSnippetItemChannelId], Name = info.ChannelCodeSnippetItemName, Code = info.ChannelCodeSnippetItemCode, + DisplayMode = info.ChannelCodeSnippetAdministrationDisplayMode, TagType = info.ChannelCodeSnippetItemType, ConsentIDs = info.ChannelCodeSnippetItemConsentId == 0 ? [] : [info.ChannelCodeSnippetItemConsentId], TagIdentifier = info.ChannelCodeSnippetItemIdentifier, diff --git a/src/Kentico.Xperience.TagManager/Rendering/CodeSnippetAdministrationDisplayMode.cs b/src/Kentico.Xperience.TagManager/Rendering/CodeSnippetAdministrationDisplayMode.cs new file mode 100644 index 0000000..3e734c6 --- /dev/null +++ b/src/Kentico.Xperience.TagManager/Rendering/CodeSnippetAdministrationDisplayMode.cs @@ -0,0 +1,9 @@ +namespace Kentico.Xperience.TagManager.Rendering; + +public enum CodeSnippetAdministrationDisplayMode +{ + None = default, + PreviewOnly, + PageBuilderOnly, + Both +} diff --git a/src/Kentico.Xperience.TagManager/Rendering/CodeSnippetDto.cs b/src/Kentico.Xperience.TagManager/Rendering/CodeSnippetDto.cs index d3fd2d5..2f49d65 100644 --- a/src/Kentico.Xperience.TagManager/Rendering/CodeSnippetDto.cs +++ b/src/Kentico.Xperience.TagManager/Rendering/CodeSnippetDto.cs @@ -5,4 +5,5 @@ public class CodeSnippetDto public int ID { get; init; } public string? Code { get; init; } public CodeSnippetLocations Location { get; init; } + public CodeSnippetAdministrationDisplayMode DisplayMode { get; set; } } diff --git a/src/Kentico.Xperience.TagManager/Rendering/CodeSnippetTagHelperComponent.cs b/src/Kentico.Xperience.TagManager/Rendering/CodeSnippetTagHelperComponent.cs index 6eea5db..0b3c8ca 100644 --- a/src/Kentico.Xperience.TagManager/Rendering/CodeSnippetTagHelperComponent.cs +++ b/src/Kentico.Xperience.TagManager/Rendering/CodeSnippetTagHelperComponent.cs @@ -1,6 +1,11 @@ using CMS.ContactManagement; +using Kentico.Content.Web.Mvc; +using Kentico.PageBuilder.Web.Mvc; +using Kentico.Web.Mvc; + using Microsoft.AspNetCore.Html; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Mvc.Routing; using Microsoft.AspNetCore.Mvc.ViewFeatures; @@ -18,14 +23,17 @@ internal class CodeSnippetTagHelperComponent : TagHelperComponent private readonly IChannelCodeSnippetsService codeSnippetsContext; private readonly IUrlHelperFactory urlHelperFactory; private readonly IFileVersionProvider fileVersionProvider; + private readonly IHttpContextAccessor httpContextAccessor; public CodeSnippetTagHelperComponent( IChannelCodeSnippetsService codeSnippetsContext, IUrlHelperFactory urlHelperFactory, - IFileVersionProvider fileVersionProvider) + IFileVersionProvider fileVersionProvider, + IHttpContextAccessor httpContextAccessor) { this.codeSnippetsContext = codeSnippetsContext; this.urlHelperFactory = urlHelperFactory; + this.httpContextAccessor = httpContextAccessor; this.fileVersionProvider = fileVersionProvider; } @@ -40,27 +48,53 @@ public override async Task ProcessAsync(TagHelperContext context, TagHelperOutpu { var contact = ContactManagementContext.CurrentContact; + var codeSnippets = await codeSnippetsContext.GetConsentedCodeSnippets(contact); + if (string.Equals(context.TagName, HeadTag, StringComparison.OrdinalIgnoreCase)) { - ProcessHead(output, await codeSnippetsContext.GetConsentedCodeSnippets(contact)); + ProcessHead(output, codeSnippets, httpContextAccessor.HttpContext); } if (string.Equals(context.TagName, BodyTag, StringComparison.OrdinalIgnoreCase)) { - ProcessBody(output, await codeSnippetsContext.GetConsentedCodeSnippets(contact)); + ProcessBody(output, codeSnippets, httpContextAccessor.HttpContext); } } private static void ProcessHead( TagHelperOutput output, - ILookup codeSnippets) + ILookup codeSnippets, + HttpContext? httpContext) { - foreach (var codeSnippet in codeSnippets[CodeSnippetLocations.HeadTop]) + bool isEditMode = httpContext.Kentico().PageBuilder().EditMode; + bool isPreviewMode = httpContext.Kentico().Preview().Enabled; + + var headTopSnippets = codeSnippets[CodeSnippetLocations.HeadTop]; + var headBottomSnippets = codeSnippets[CodeSnippetLocations.HeadBottom]; + + if (isEditMode) + { + headTopSnippets = headTopSnippets.Where(x => x.DisplayMode is CodeSnippetAdministrationDisplayMode.Both or + CodeSnippetAdministrationDisplayMode.PageBuilderOnly); + + headBottomSnippets = headBottomSnippets.Where(x => x.DisplayMode is CodeSnippetAdministrationDisplayMode.Both or + CodeSnippetAdministrationDisplayMode.PageBuilderOnly); + } + else if (isPreviewMode) + { + headTopSnippets = headTopSnippets.Where(x => x.DisplayMode is CodeSnippetAdministrationDisplayMode.Both or + CodeSnippetAdministrationDisplayMode.PreviewOnly); + + headBottomSnippets = headBottomSnippets.Where(x => x.DisplayMode is CodeSnippetAdministrationDisplayMode.Both or + CodeSnippetAdministrationDisplayMode.PreviewOnly); + } + + foreach (var codeSnippet in headTopSnippets) { output.PreContent.AppendHtml(codeSnippet.Code); } - foreach (var codeSnippet in codeSnippets[CodeSnippetLocations.HeadBottom]) + foreach (var codeSnippet in headBottomSnippets) { output.PostContent.AppendHtml(codeSnippet.Code); } @@ -68,14 +102,38 @@ private static void ProcessHead( private void ProcessBody( TagHelperOutput output, - ILookup codeSnippets) + ILookup codeSnippets, + HttpContext? httpContext) { - foreach (var codeSnippet in codeSnippets[CodeSnippetLocations.BodyTop]) + bool isEditMode = httpContext.Kentico().PageBuilder().EditMode; + bool isPreviewMode = httpContext.Kentico().Preview().Enabled; + + var bodyTopSnippets = codeSnippets[CodeSnippetLocations.BodyTop]; + var bodyBottomSnippets = codeSnippets[CodeSnippetLocations.BodyBottom]; + + if (isEditMode) + { + bodyTopSnippets = bodyTopSnippets.Where(x => x.DisplayMode is CodeSnippetAdministrationDisplayMode.Both or + CodeSnippetAdministrationDisplayMode.PageBuilderOnly); + + bodyBottomSnippets = bodyBottomSnippets.Where(x => x.DisplayMode is CodeSnippetAdministrationDisplayMode.Both or + CodeSnippetAdministrationDisplayMode.PageBuilderOnly); + } + else if (isPreviewMode) + { + bodyTopSnippets = bodyTopSnippets.Where(x => x.DisplayMode is CodeSnippetAdministrationDisplayMode.Both or + CodeSnippetAdministrationDisplayMode.PreviewOnly); + + bodyBottomSnippets = bodyBottomSnippets.Where(x => x.DisplayMode is CodeSnippetAdministrationDisplayMode.Both or + CodeSnippetAdministrationDisplayMode.PreviewOnly); + } + + foreach (var codeSnippet in bodyTopSnippets) { output.PreContent.AppendHtml(codeSnippet.Code); } - foreach (var codeSnippet in codeSnippets[CodeSnippetLocations.BodyBottom]) + foreach (var codeSnippet in bodyBottomSnippets) { output.PostContent.AppendHtml(codeSnippet.Code); } diff --git a/src/Kentico.Xperience.TagManager/Rendering/DefaultChannelCodeSnippetsService.cs b/src/Kentico.Xperience.TagManager/Rendering/DefaultChannelCodeSnippetsService.cs index 3ff7e31..4ce22d7 100644 --- a/src/Kentico.Xperience.TagManager/Rendering/DefaultChannelCodeSnippetsService.cs +++ b/src/Kentico.Xperience.TagManager/Rendering/DefaultChannelCodeSnippetsService.cs @@ -17,6 +17,7 @@ internal class DefaultChannelCodeSnippetsService : IChannelCodeSnippetsService { private readonly IConsentAgreementService consentAgreementService; private readonly IWebsiteChannelContext channelContext; + private readonly IChannelCodeSnippetItemInfoProvider codeSnippetInfoProvider; private readonly IProgressiveCache cache; @@ -70,6 +71,7 @@ async Task> GetCodeSnippetsInterna .Columns(nameof(ChannelCodeSnippetItemInfo.ChannelCodeSnippetItemLocation), nameof(ChannelCodeSnippetItemInfo.ChannelCodeSnippetItemCode), nameof(ChannelCodeSnippetItemInfo.ChannelCodeSnippetItemConsentId), + nameof(ChannelCodeSnippetItemInfo.ChannelCodeSnippetAdministrationDisplayMode), nameof(ChannelCodeSnippetItemInfo.ChannelCodeSnippetItemIdentifier), nameof(ChannelCodeSnippetItemInfo.ChannelCodeSnippetItemID), nameof(ChannelCodeSnippetItemInfo.ChannelCodeSnippetItemType), @@ -99,13 +101,18 @@ private static IEnumerable CreateCodeSnippet(ChannelCodeSnippetI var tags = new List(); + if (!Enum.TryParse(snippetInfo.ChannelCodeSnippetAdministrationDisplayMode, out CodeSnippetAdministrationDisplayMode displayMode)) + { + displayMode = CodeSnippetAdministrationDisplayMode.None; + } if (snippetSettings.TagTypeName != CustomSnippetFactory.TAG_TYPE_NAME) { tags.AddRange(snippetFactory.CreateCodeSnippets(snippetInfo.ChannelCodeSnippetItemIdentifier).Select(x => new CodeSnippetDto { Location = x.Location, Code = x.Code, - ID = snippetInfo.ChannelCodeSnippetItemID + ID = snippetInfo.ChannelCodeSnippetItemID, + DisplayMode = displayMode })); } else @@ -117,6 +124,7 @@ private static IEnumerable CreateCodeSnippet(ChannelCodeSnippetI Location = Enum.TryParse(snippetInfo.ChannelCodeSnippetItemLocation, out CodeSnippetLocations location) ? location : throw new InvalidOperationException("Invalid Channel Tag Location."), + DisplayMode = displayMode }); tags.Add(tag); @@ -130,7 +138,8 @@ private static CodeSnippetDto AdjustCustomCodeSnippet(CodeSnippetDto codeSnippet { Code = codeSnippet.Code != null ? AddSnippetIds(codeSnippet.ID, codeSnippet.Code!) : codeSnippet.Code, ID = codeSnippet.ID, - Location = codeSnippet.Location + Location = codeSnippet.Location, + DisplayMode = codeSnippet.DisplayMode }; private static string AddSnippetIds(int codeSnippetId, string codeSnippet) =>