diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Common/Converters/SeoValueConverters/BaseGridSeoValueConverter.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Common/Converters/SeoValueConverters/BaseGridSeoValueConverter.cs new file mode 100644 index 00000000..344a96bf --- /dev/null +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Common/Converters/SeoValueConverters/BaseGridSeoValueConverter.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Umbraco.Cms.Core.Models.PublishedContent; +using Umbraco.Cms.Core.Models.Blocks; +using Umbraco.Extensions; +using SeoToolkit.Umbraco.MetaFields.Core.Interfaces.Converters; +using Umbraco.Cms.Core.Strings; + +namespace SeoToolkit.Umbraco.MetaFields.Core.Common.Converters.SeoValueConverters +{ + public abstract class BaseGridSeoValueConverter : ISeoValueConverter + where T : class, IBlockReference + { + public virtual Type FromValue {get;} + public virtual Type ToValue {get;} + public virtual object Convert(object value, IPublishedContent currentContent, string fieldAlias) + { + var dataTypes = new string[]{ + global::Umbraco.Cms.Core.Constants.PropertyEditors.Aliases.TextArea, + global::Umbraco.Cms.Core.Constants.PropertyEditors.Aliases.TextBox, + global::Umbraco.Cms.Core.Constants.PropertyEditors.Aliases.TinyMce + }; + // Walk the Block List and get any text values in a list. + List values = new(); + if (value is BlockModelCollection blocks) { + foreach(var item in blocks.Select(b => b.Content)) + { + // Go through each of the properties in the content element that are Text, Text Area or Rich Text and aggregate their values into a single string. + foreach(var property in item.Properties.Where(p => dataTypes.Contains(p.PropertyType.DataType.EditorAlias))) { + var propertyValue = item.Value(property.Alias); + if (propertyValue is IHtmlEncodedString encodedString) { + values.Add(encodedString.ToHtmlString()?.StripHtml()); + } else { + values.Add(propertyValue); + } + + // TODO: If there is an embedded Block Grid or Block List item, recurse into it and get the values. + } + } + } + return values.Aggregate("", (a, b) => $"{a} {b}").Trim(); + } + } +} diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Common/Converters/SeoValueConverters/BlockGridSeoValueConverter.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Common/Converters/SeoValueConverters/BlockGridSeoValueConverter.cs new file mode 100644 index 00000000..20397df9 --- /dev/null +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Common/Converters/SeoValueConverters/BlockGridSeoValueConverter.cs @@ -0,0 +1,11 @@ +using System; +using Umbraco.Cms.Core.Models.Blocks; + +namespace SeoToolkit.Umbraco.MetaFields.Core.Common.Converters.SeoValueConverters +{ + public class BlockGridSeoValueConverter : BaseGridSeoValueConverter + { + public override Type FromValue => typeof(BlockGridModel); + public override Type ToValue => typeof(string); + } +} diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Common/Converters/SeoValueConverters/BlockListSeoValueConverter.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Common/Converters/SeoValueConverters/BlockListSeoValueConverter.cs new file mode 100644 index 00000000..82e3c534 --- /dev/null +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Common/Converters/SeoValueConverters/BlockListSeoValueConverter.cs @@ -0,0 +1,11 @@ +using System; +using Umbraco.Cms.Core.Models.Blocks; + +namespace SeoToolkit.Umbraco.MetaFields.Core.Common.Converters.SeoValueConverters +{ + public class BlockListSeoValueConverter : BaseGridSeoValueConverter + { + public override Type FromValue => typeof(BlockListModel); + public override Type ToValue => typeof(string); + } +} diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Composers/MetaFieldsComposer.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Composers/MetaFieldsComposer.cs index 43baf015..972e7999 100644 --- a/src/SeoToolkit.Umbraco.MetaFields.Core/Composers/MetaFieldsComposer.cs +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Composers/MetaFieldsComposer.cs @@ -85,6 +85,8 @@ public void Compose(IUmbracoBuilder builder) .Add() .Add() .Add() + .Add() + .Add() .Add(); builder.WithCollectionBuilder() diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphDescriptionField.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphDescriptionField.cs index 5a59af3f..5d1d9655 100644 --- a/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphDescriptionField.cs +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphDescriptionField.cs @@ -17,7 +17,13 @@ public class OpenGraphDescriptionField : ISeoField public string GroupAlias => SeoFieldGroupConstants.SocialMediaGroup; public Type FieldType => typeof(string); - public ISeoFieldEditor Editor => new SeoFieldFieldsEditor(new[] { "Umbraco.TextBox", "Umbraco.TextArea", "Umbraco.TinyMCE" }); + public ISeoFieldEditor Editor => new SeoFieldFieldsEditor(new[] { + global::Umbraco.Cms.Core.Constants.PropertyEditors.Aliases.TextArea, + global::Umbraco.Cms.Core.Constants.PropertyEditors.Aliases.TextBox, + global::Umbraco.Cms.Core.Constants.PropertyEditors.Aliases.TinyMce, + global::Umbraco.Cms.Core.Constants.PropertyEditors.Aliases.BlockGrid, + global::Umbraco.Cms.Core.Constants.PropertyEditors.Aliases.BlockList, + }); public ISeoFieldEditEditor EditEditor => new SeoTextAreaEditEditor(); public HtmlString Render(object value) diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/SeoDescriptionField.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/SeoDescriptionField.cs index a768cdfc..daf40a31 100644 --- a/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/SeoDescriptionField.cs +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/SeoDescriptionField.cs @@ -17,7 +17,13 @@ public class SeoDescriptionField : ISeoField public string GroupAlias => SeoFieldGroupConstants.MetaFieldsGroup; public Type FieldType => typeof(string); - public ISeoFieldEditor Editor => new SeoFieldFieldsEditor(new[] { "Umbraco.TextBox", "Umbraco.TextArea", "Umbraco.TinyMCE" }); + public ISeoFieldEditor Editor => new SeoFieldFieldsEditor(new[] { + global::Umbraco.Cms.Core.Constants.PropertyEditors.Aliases.TextArea, + global::Umbraco.Cms.Core.Constants.PropertyEditors.Aliases.TextBox, + global::Umbraco.Cms.Core.Constants.PropertyEditors.Aliases.TinyMce, + global::Umbraco.Cms.Core.Constants.PropertyEditors.Aliases.BlockGrid, + global::Umbraco.Cms.Core.Constants.PropertyEditors.Aliases.BlockList, + }); public ISeoFieldEditEditor EditEditor => new SeoTextAreaEditEditor(); public HtmlString Render(object value) diff --git a/src/SeoToolkit.Umbraco.MetaFields/wwwroot/MetaFields/Interface/ContentApps/SeoSettings/seoSettings.controller.js b/src/SeoToolkit.Umbraco.MetaFields/wwwroot/MetaFields/Interface/ContentApps/SeoSettings/seoSettings.controller.js index 81eb4c2f..1c191b9a 100644 --- a/src/SeoToolkit.Umbraco.MetaFields/wwwroot/MetaFields/Interface/ContentApps/SeoSettings/seoSettings.controller.js +++ b/src/SeoToolkit.Umbraco.MetaFields/wwwroot/MetaFields/Interface/ContentApps/SeoSettings/seoSettings.controller.js @@ -19,11 +19,13 @@ vm.isContentDirty = function () { var currentEditorItem = editorState.getCurrent(); var isDirty = false; - currentEditorItem.variants.forEach(function (variant) { - if (variant.isDirty) { - isDirty = true; - } - }); + if (currentEditorItem.variants !== undefined) { + currentEditorItem.variants.forEach(function (variant) { + if (variant.isDirty) { + isDirty = true; + } + }); + } return isDirty; }