diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Common/Converters/SeoValueConverters/TextSeoValueConverter.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Common/Converters/SeoValueConverters/TextSeoValueConverter.cs index b31cf26d..e939e024 100644 --- a/src/SeoToolkit.Umbraco.MetaFields.Core/Common/Converters/SeoValueConverters/TextSeoValueConverter.cs +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Common/Converters/SeoValueConverters/TextSeoValueConverter.cs @@ -9,6 +9,7 @@ public class TextSeoValueConverter : ISeoValueConverter { public Type FromValue => typeof(string); public Type ToValue => typeof(string); + public object Convert(object value, IPublishedContent currentContent, string fieldAlias) { var stringValue = value?.ToString(); @@ -20,9 +21,24 @@ public object Convert(object value, IPublishedContent currentContent, string fie { url = url.TrimEnd('/'); } + return stringValue.Replace("%CurrentUrl%", url); } + else if (stringValue?.Contains("%CurrentLang%") is true) + { + var lang = currentContent.GetCultureFromDomains(); + + return stringValue.Replace("%CurrentLang%", lang); + } + + else if (stringValue?.Contains("%CurrentPageName%") is true) + { + var name = currentContent.Name(); + + return stringValue.Replace("%CurrentPageName%", name); + } + return stringValue; } } -} +} \ No newline at end of file diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Common/SeoFieldEditEditors/SeoVideoEditEditor.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Common/SeoFieldEditEditors/SeoVideoEditEditor.cs new file mode 100644 index 00000000..9831cda9 --- /dev/null +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Common/SeoFieldEditEditors/SeoVideoEditEditor.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; +using Umbraco.Cms.Core.Web; +using SeoToolkit.Umbraco.MetaFields.Core.Common.Converters.EditorConverters; +using SeoToolkit.Umbraco.MetaFields.Core.Interfaces.Converters; +using SeoToolkit.Umbraco.MetaFields.Core.Interfaces.SeoField; + +namespace SeoToolkit.Umbraco.MetaFields.Core.Common.SeoFieldEditEditors +{ + public class SeoVideoEditEditor : ISeoFieldEditEditor + { + public string View => "mediapicker"; + public Dictionary Config { get; } + public IEditorValueConverter ValueConverter { get; } + + public SeoVideoEditEditor(IUmbracoContextFactory umbracoContextFactory) + { + ValueConverter = new UmbracoMediaUdiConverter(umbracoContextFactory); + Config = new Dictionary + { + {"disableFolderSelect", false}, + {"idType", "udi"}, + {"ignoreUserStartNodes", false}, + {"multiPicker", false}, + {"onlyImages", false} + }; + } + } +} diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Common/SeoFieldEditors/DropdownFieldPropertyEditor.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Common/SeoFieldEditors/DropdownFieldPropertyEditor.cs index 59190481..7c3e66cc 100644 --- a/src/SeoToolkit.Umbraco.MetaFields.Core/Common/SeoFieldEditors/DropdownFieldPropertyEditor.cs +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Common/SeoFieldEditors/DropdownFieldPropertyEditor.cs @@ -6,9 +6,14 @@ namespace SeoToolkit.Umbraco.MetaFields.Core.Common.SeoFieldEditors public class DropdownFieldPropertyEditor : SeoFieldPropertyEditor, ISeoFieldEditorProcessor { - public DropdownFieldPropertyEditor(string[] items) : base("/App_Plugins/SeoToolkit/MetaFields/Interface/SeoFieldEditors/PropertyEditor/dropdownList.html", new TextValueConverter()) + public DropdownFieldPropertyEditor(string[] items,string defaultValue = "") : base("/App_Plugins/SeoToolkit/MetaFields/Interface/SeoFieldEditors/PropertyEditor/dropdownList.html", new TextValueConverter()) { IsPreValue = true; + if (!string.IsNullOrEmpty(defaultValue)) + { + SetDefaultValue(defaultValue); + } + Config.Add("items", items); } diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Common/SeoFieldGroups/OpenGraphFieldsGroup.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Common/SeoFieldGroups/OpenGraphFieldsGroup.cs new file mode 100644 index 00000000..a3fcd342 --- /dev/null +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Common/SeoFieldGroups/OpenGraphFieldsGroup.cs @@ -0,0 +1,13 @@ +using SeoToolkit.Umbraco.MetaFields.Core.Constants; +using SeoToolkit.Umbraco.MetaFields.Core.Interfaces.SeoField; + +namespace SeoToolkit.Umbraco.MetaFields.Core.Common.SeoFieldGroups +{ + public class OpenGraphFieldsGroup : ISeoFieldGroup + { + public string Alias => SeoFieldGroupConstants.OpenGraphGroup; + public string Name => "Open Graph"; + public string Description => "Fields that indicate how your page will look on social media platforms"; + public ISeoFieldPreviewer Previewer { get; } + } +} diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Common/SeoFieldGroups/TwitterFieldsGroup.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Common/SeoFieldGroups/TwitterFieldsGroup.cs new file mode 100644 index 00000000..f9a5450d --- /dev/null +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Common/SeoFieldGroups/TwitterFieldsGroup.cs @@ -0,0 +1,13 @@ +using SeoToolkit.Umbraco.MetaFields.Core.Constants; +using SeoToolkit.Umbraco.MetaFields.Core.Interfaces.SeoField; + +namespace SeoToolkit.Umbraco.MetaFields.Core.Common.SeoFieldGroups +{ + public class TwitterFieldsGroup : ISeoFieldGroup + { + public string Alias => SeoFieldGroupConstants.TwitterGroup; + public string Name => "Twitter"; + public string Description => "Fields that indicate how your page will look on twitter"; + public ISeoFieldPreviewer Previewer { get; } + } +} diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Common/SeoFieldPreviewers/OpenGraphPreviewer.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Common/SeoFieldPreviewers/OpenGraphPreviewer.cs new file mode 100644 index 00000000..bd90dcd5 --- /dev/null +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Common/SeoFieldPreviewers/OpenGraphPreviewer.cs @@ -0,0 +1,11 @@ +using SeoToolkit.Umbraco.MetaFields.Core.Constants; +using SeoToolkit.Umbraco.MetaFields.Core.Interfaces.SeoField; + +namespace SeoToolkit.Umbraco.MetaFields.Core.Common.SeoFieldPreviewers +{ + public class OpenGraphPreviewer : ISeoFieldPreviewer + { + public string Group => SeoFieldGroupConstants.OpenGraphGroup; + public string View => "/App_Plugins/SeoToolkit/MetaFields/Interface/Previewers/OpenGraph/openGraphPreviewer.html"; + } +} diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Common/SeoFieldPreviewers/TwitterPreviewer.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Common/SeoFieldPreviewers/TwitterPreviewer.cs new file mode 100644 index 00000000..60bb1ff0 --- /dev/null +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Common/SeoFieldPreviewers/TwitterPreviewer.cs @@ -0,0 +1,11 @@ +using SeoToolkit.Umbraco.MetaFields.Core.Constants; +using SeoToolkit.Umbraco.MetaFields.Core.Interfaces.SeoField; + +namespace SeoToolkit.Umbraco.MetaFields.Core.Common.SeoFieldPreviewers +{ + public class TwitterPreviewer : ISeoFieldPreviewer + { + public string Group => SeoFieldGroupConstants.TwitterGroup; + public string View => "/App_Plugins/SeoToolkit/MetaFields/Interface/Previewers/OpenGraph/openGraphPreviewer.html"; + } +} diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Common/TagHelpers/MetaFieldsTagHelper.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Common/TagHelpers/MetaFieldsTagHelper.cs index 2cb0267e..e2377a1a 100644 --- a/src/SeoToolkit.Umbraco.MetaFields.Core/Common/TagHelpers/MetaFieldsTagHelper.cs +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Common/TagHelpers/MetaFieldsTagHelper.cs @@ -1,8 +1,10 @@ using System.Text; using Microsoft.AspNetCore.Html; +using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using Microsoft.AspNetCore.Razor.TagHelpers; using Umbraco.Cms.Core.Web; using SeoToolkit.Umbraco.MetaFields.Core.Interfaces.Services; +using SeoToolkit.Umbraco.MetaFields.Core.Models.Converters; namespace SeoToolkit.Umbraco.MetaFields.Core.Common.TagHelpers { @@ -31,6 +33,11 @@ public override void Process(TagHelperContext context, TagHelperOutput output) //TODO: We should probably have a special IsEmpty check here? if (string.IsNullOrWhiteSpace(value?.ToString())) continue; + if (value is FieldsModel) + { + + continue; + } stringBuilder.AppendLine(key.Render(value).ToString()); } diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Composers/MetaFieldsComposer.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Composers/MetaFieldsComposer.cs index 972e7999..b72082f0 100644 --- a/src/SeoToolkit.Umbraco.MetaFields.Core/Composers/MetaFieldsComposer.cs +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Composers/MetaFieldsComposer.cs @@ -67,12 +67,20 @@ public void Compose(IUmbracoBuilder builder) .Add() .Add() .Add() + .Add() + .Add() + .Add() + .Add() .Add() .Add() .Add() .Add() .Add() .Add() + .Add() + .Add() + .Add() + .Add() .Add(); if (settings?.ShowKeywordsField is true) diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Constants/SeoFieldAliasConstants.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Constants/SeoFieldAliasConstants.cs index 3c0d011c..2032b7d7 100644 --- a/src/SeoToolkit.Umbraco.MetaFields.Core/Constants/SeoFieldAliasConstants.cs +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Constants/SeoFieldAliasConstants.cs @@ -6,16 +6,28 @@ public static class SeoFieldAliasConstants public const string Keywords = "keywords"; public const string Schema = "schema"; public const string MetaDescription = "metaDescription"; - public const string OpenGraphTitle = "openGraphTitle"; - public const string OpenGraphDescription = "openGraphDescription"; - public const string OpenGraphImage = "openGraphImage"; + public const string CanonicalUrl = "canonicalUrl"; public const string Robots = "robots"; + + public const string OpenGraphTitle = "openGraphTitle"; + public const string OpenGraphDescription = "openGraphDescription"; + public const string OpenGraphImage = "openGraphImage"; public const string OpenGraphUrl = "openGraphUrl"; + public const string OpenGraphType = "openGraphType"; + public const string OpenGraphLocale = "openGraphLocale"; + public const string OpenGraphSiteName = "openGraphSiteName"; + public const string OpenGraphVideo = "openGraphVideo"; + public const string TwitterCardType = "twitterCardType"; public const string TwitterSite = "twitterSite"; public const string TwitterCreator = "twitterCreator"; + public const string TwitterTitle = "twitterTitle"; + public const string TwitterDescription = "twitterDescription"; + public const string TwitterImage = "twitterImage"; + public const string TwitterUrl = "twitterUrl"; + public const string FacebookId = "facebookId"; } diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Constants/SeoFieldGroupConstants.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Constants/SeoFieldGroupConstants.cs index 30c29642..54f68ad7 100644 --- a/src/SeoToolkit.Umbraco.MetaFields.Core/Constants/SeoFieldGroupConstants.cs +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Constants/SeoFieldGroupConstants.cs @@ -4,7 +4,8 @@ public static class SeoFieldGroupConstants { public const string MetaFieldsGroup = "metaFields"; public const string SocialMediaGroup = "socialMedia"; - // public const string TwitterGroup = "twitter"; + public const string OpenGraphGroup = "openGraph"; + public const string TwitterGroup = "twitter"; // public const string FacebookGroup = "facebook"; public const string Others = "others"; } diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Controllers/MetaFieldsController.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Controllers/MetaFieldsController.cs index 1a542b5e..6d8aaaf1 100644 --- a/src/SeoToolkit.Umbraco.MetaFields.Core/Controllers/MetaFieldsController.cs +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Controllers/MetaFieldsController.cs @@ -90,7 +90,7 @@ public IActionResult Get(int nodeId, string culture) EditConfig = key.EditEditor.Config }; }).ToArray(), - Previewers = new[] { new FieldPreviewerViewModel(new MetaFieldsPreviewer()), new FieldPreviewerViewModel(new SocialMediaPreviewer()) } + Previewers = new[] { new FieldPreviewerViewModel(new MetaFieldsPreviewer()), new FieldPreviewerViewModel(new SocialMediaPreviewer()), new FieldPreviewerViewModel(new OpenGraphPreviewer()) , new FieldPreviewerViewModel(new TwitterPreviewer())} }); } diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/FacebookIdField.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/FacebookIdField.cs index 7e662028..bc754641 100644 --- a/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/FacebookIdField.cs +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/FacebookIdField.cs @@ -11,7 +11,7 @@ namespace SeoToolkit.Umbraco.MetaFields.Core.Models.SeoField; [Weight(701)] public class FacebookIdField : SeoField { - public override string Title => "App Id"; + public override string Title => "Facebook App Id"; public override string Alias => SeoFieldAliasConstants.FacebookId; public override string Description => "Facebook app_id for the content"; public override string GroupAlias => SeoFieldGroupConstants.SocialMediaGroup; diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphDescriptionField.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphDescriptionField.cs index 5d1d9655..6c3cf477 100644 --- a/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphDescriptionField.cs +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphDescriptionField.cs @@ -1,10 +1,10 @@ using System; using Microsoft.AspNetCore.Html; -using Umbraco.Cms.Core.Composing; using SeoToolkit.Umbraco.MetaFields.Core.Common.SeoFieldEditEditors; using SeoToolkit.Umbraco.MetaFields.Core.Constants; using SeoToolkit.Umbraco.MetaFields.Core.Interfaces.SeoField; using SeoToolkit.Umbraco.MetaFields.Core.Models.SeoFieldEditors; +using Umbraco.Cms.Core.Composing; namespace SeoToolkit.Umbraco.MetaFields.Core.Models.SeoField { @@ -14,7 +14,7 @@ public class OpenGraphDescriptionField : ISeoField public string Title => "Open Graph Description"; public string Alias => SeoFieldAliasConstants.OpenGraphDescription; public string Description => "Description for Open Graph"; - public string GroupAlias => SeoFieldGroupConstants.SocialMediaGroup; + public string GroupAlias => SeoFieldGroupConstants.OpenGraphGroup; public Type FieldType => typeof(string); public ISeoFieldEditor Editor => new SeoFieldFieldsEditor(new[] { diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphImageField.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphImageField.cs index 9c97f68a..e817b641 100644 --- a/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphImageField.cs +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphImageField.cs @@ -1,47 +1,75 @@ using System; +using System.Linq; using Microsoft.AspNetCore.Html; -using Umbraco.Cms.Core.Composing; -using Umbraco.Cms.Core.Models.PublishedContent; -using Umbraco.Cms.Core.Web; -using Umbraco.Extensions; using SeoToolkit.Umbraco.MetaFields.Core.Common.SeoFieldEditEditors; +using SeoToolkit.Umbraco.MetaFields.Core.Common.SeoFieldEditors; using SeoToolkit.Umbraco.MetaFields.Core.Constants; using SeoToolkit.Umbraco.MetaFields.Core.Interfaces.SeoField; using SeoToolkit.Umbraco.MetaFields.Core.Models.SeoFieldEditors; +using Umbraco.Cms.Core.Composing; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Models.PublishedContent; +using Umbraco.Cms.Core.Routing; +using Umbraco.Cms.Core.Web; +using Umbraco.Extensions; namespace SeoToolkit.Umbraco.MetaFields.Core.Models.SeoField { [Weight(500)] - public class OpenGraphImageField : ISeoField + public class OpenGraphImageField : SeoField { private readonly IUmbracoContextFactory _umbracoContextFactory; - public string Title => "Open Graph Image"; - public string Alias => SeoFieldAliasConstants.OpenGraphImage; - public string Description => "Image for Open Graph"; - public string GroupAlias => SeoFieldGroupConstants.SocialMediaGroup; - public Type FieldType => typeof(string); + public override string Title => "Open Graph Image"; + public override string Alias => SeoFieldAliasConstants.OpenGraphImage; + public override string Description => "Image for Open Graph"; + public override string GroupAlias => SeoFieldGroupConstants.OpenGraphGroup; + - public ISeoFieldEditor Editor => new SeoFieldFieldsEditor(new[] { "Umbraco.MediaPicker", "Umbraco.MediaPicker3" }); - public ISeoFieldEditEditor EditEditor => new SeoImageEditEditor(_umbracoContextFactory); + public override ISeoFieldEditor Editor => new SeoFieldFieldsEditor(new[] { "Umbraco.MediaPicker", "Umbraco.MediaPicker3" }); + public override ISeoFieldEditEditor EditEditor => new SeoImageEditEditor(_umbracoContextFactory); public OpenGraphImageField(IUmbracoContextFactory umbracoContextFactory) { _umbracoContextFactory = umbracoContextFactory; + + } + - public HtmlString Render(object value) + protected override HtmlString Render(IPublishedContent value) { string url; - if (value is IPublishedContent media) + string height = string.Empty; + string width = string.Empty; + string type = string.Empty; + if (value is { } media) { url = media.Url(mode: UrlMode.Absolute); + width = media.Value("umbracoWidth"); + height = media.Value("umbracoHeight"); + type = media.Value("umbracoExtension"); } else { url = value?.ToString(); } - return new HtmlString($""); + var html = $""; + if (!string.IsNullOrEmpty(width)) + { + html += $""; + } + if (!string.IsNullOrEmpty(height)) + { + html += $""; + } + if (!string.IsNullOrEmpty(type)) + { + html += $""; + } + + + return new HtmlString(html); } } -} +} \ No newline at end of file diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphLocaleField.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphLocaleField.cs new file mode 100644 index 00000000..b910052a --- /dev/null +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphLocaleField.cs @@ -0,0 +1,35 @@ +using Microsoft.AspNetCore.Html; +using SeoToolkit.Umbraco.MetaFields.Core.Common.SeoFieldEditEditors; +using SeoToolkit.Umbraco.MetaFields.Core.Common.SeoFieldEditors; +using SeoToolkit.Umbraco.MetaFields.Core.Constants; +using SeoToolkit.Umbraco.MetaFields.Core.Interfaces.SeoField; +using Umbraco.Cms.Core.Composing; +using Umbraco.Extensions; + +namespace SeoToolkit.Umbraco.MetaFields.Core.Models.SeoField; + +[Weight(600)] +public class OpenGraphLocaleField : SeoField +{ + public override string Title => "Open Graph Locale"; + public override string Alias => SeoFieldAliasConstants.OpenGraphLocale; + public override string Description => "Defines the content language."; + public override string GroupAlias => SeoFieldGroupConstants.OpenGraphGroup; + public override ISeoFieldEditor Editor { get; } + public override ISeoFieldEditEditor EditEditor => new SeoTextBoxEditEditor(); + + + public OpenGraphLocaleField() + { + var propertyEditor = new SeoFieldPropertyEditor("textbox"); + propertyEditor.SetExtraInformation("Defines the content language."); + propertyEditor.SetDefaultValue("%CurrentLang%"); + + Editor = propertyEditor; + } + + protected override HtmlString Render(string value) + { + return new HtmlString(value.IsNullOrWhiteSpace() ? null : $""); + } +} \ No newline at end of file diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphSiteNameField.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphSiteNameField.cs new file mode 100644 index 00000000..ac659f1c --- /dev/null +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphSiteNameField.cs @@ -0,0 +1,35 @@ +using Microsoft.AspNetCore.Html; +using SeoToolkit.Umbraco.MetaFields.Core.Common.Converters.EditorConverters; +using SeoToolkit.Umbraco.MetaFields.Core.Common.SeoFieldEditEditors; +using SeoToolkit.Umbraco.MetaFields.Core.Common.SeoFieldEditors; +using SeoToolkit.Umbraco.MetaFields.Core.Constants; +using SeoToolkit.Umbraco.MetaFields.Core.Interfaces.SeoField; +using Umbraco.Cms.Core.Composing; +using Umbraco.Extensions; + +namespace SeoToolkit.Umbraco.MetaFields.Core.Models.SeoField; + +[Weight(600)] +public class OpenGraphSiteNameField : SeoField +{ + public override string Title => "Open Graph Site Name"; + public override string Alias => SeoFieldAliasConstants.OpenGraphSiteName; + public override string Description => "Defines the website name."; + public override string GroupAlias => SeoFieldGroupConstants.OpenGraphGroup; + public override ISeoFieldEditor Editor { get; } + public override ISeoFieldEditEditor EditEditor => new SeoTextBoxEditEditor(); + + public OpenGraphSiteNameField() + { + var propertyEditor = new SeoFieldPropertyEditor("textbox"); + // propertyEditor.SetExtraInformation("Defines the content language."); + // propertyEditor.SetDefaultValue("%CurrentLang%"); + + Editor = propertyEditor; + } + + protected override HtmlString Render(string value) + { + return new HtmlString(value.IsNullOrWhiteSpace() ? null : $""); + } +} \ No newline at end of file diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphTitleField.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphTitleField.cs index 178dbd68..8d5f9820 100644 --- a/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphTitleField.cs +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphTitleField.cs @@ -1,10 +1,11 @@ using System; using Microsoft.AspNetCore.Html; -using Umbraco.Cms.Core.Composing; using SeoToolkit.Umbraco.MetaFields.Core.Common.SeoFieldEditEditors; +using SeoToolkit.Umbraco.MetaFields.Core.Common.SeoFieldEditors; using SeoToolkit.Umbraco.MetaFields.Core.Constants; using SeoToolkit.Umbraco.MetaFields.Core.Interfaces.SeoField; using SeoToolkit.Umbraco.MetaFields.Core.Models.SeoFieldEditors; +using Umbraco.Cms.Core.Composing; namespace SeoToolkit.Umbraco.MetaFields.Core.Models.SeoField { @@ -14,12 +15,21 @@ public class OpenGraphTitleField : ISeoField public string Title => "Open Graph Title"; public string Alias => SeoFieldAliasConstants.OpenGraphTitle; public string Description => "Title for open graph"; - public string GroupAlias => SeoFieldGroupConstants.SocialMediaGroup; + public string GroupAlias => SeoFieldGroupConstants.OpenGraphGroup; public Type FieldType => typeof(string); - public ISeoFieldEditor Editor => new SeoFieldFieldsEditor(new[] { "Umbraco.TextBox", "Umbraco.TextArea", "Umbraco.TinyMCE" }); - public ISeoFieldEditEditor EditEditor => new SeoTextBoxEditEditor(); + public ISeoFieldEditor Editor { get; } + public ISeoFieldEditEditor EditEditor => new SeoTextBoxEditEditor(); + public OpenGraphTitleField() + { + var propertyEditor = new SeoFieldPropertyEditor("textbox"); + propertyEditor.SetExtraInformation("You can use %CurrentPageName% to display the Title of the current item"); + propertyEditor.SetDefaultValue("%CurrentPageName%"); + + Editor = propertyEditor; + } + public HtmlString Render(object value) { return new HtmlString($""); diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphTypeField.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphTypeField.cs new file mode 100644 index 00000000..3e070885 --- /dev/null +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphTypeField.cs @@ -0,0 +1,59 @@ +using Microsoft.AspNetCore.Html; +using Umbraco.Cms.Core.Composing; +using SeoToolkit.Umbraco.MetaFields.Core.Common.SeoFieldEditEditors; +using SeoToolkit.Umbraco.MetaFields.Core.Common.SeoFieldEditors; +using SeoToolkit.Umbraco.MetaFields.Core.Constants; +using SeoToolkit.Umbraco.MetaFields.Core.Interfaces.SeoField; +using SeoToolkit.Umbraco.MetaFields.Core.Models.Converters; +using Umbraco.Extensions; +using System.Collections.Generic; +using System.Linq; + +namespace SeoToolkit.Umbraco.MetaFields.Core.Models.SeoField; + +[Weight(601)] +public class OpenGraphTypeField : SeoField +{ + public override string Title => "Open Graph Type"; + public override string Alias => SeoFieldAliasConstants.OpenGraphType; + public override string Description => "Open Graph Type for your page"; + public override string GroupAlias => SeoFieldGroupConstants.OpenGraphGroup; + public override ISeoFieldEditor Editor { get; } + public override ISeoFieldEditEditor EditEditor { get; } + + public OpenGraphTypeField() + { + // App is relevant to direct download links to mobile apps; Player is relevant to video/audio media. + var items = new string[] { + "music.song", + "music.album", + "music.playlist", + "music.radio_station", + "video.movie", + "video.episode", + "video.tv_show", + "video.other", + "article", + "book", + "profile", + "website" + + }; + + var propertyEditor = new SeoDropdownEditEditor(items); + // propertyEditor.SetExtraInformation("Use one of 'summary', 'summary_large_image', 'app', 'player' or 'product'"); + // propertyEditor.SetDefaultValue("summary"); + + Editor = new DropdownFieldPropertyEditor(items,"article"); + + EditEditor = propertyEditor; + } + + protected override HtmlString Render(string value) + { + if (value is null) { + return HtmlString.Empty; + } + return new HtmlString(value.IsNullOrWhiteSpace() ? null : $""); + } +} \ No newline at end of file diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphUrlField.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphUrlField.cs index 5fa0bcbc..b1d6b072 100644 --- a/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphUrlField.cs +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphUrlField.cs @@ -1,9 +1,9 @@ using Microsoft.AspNetCore.Html; -using Umbraco.Cms.Core.Composing; using SeoToolkit.Umbraco.MetaFields.Core.Common.SeoFieldEditEditors; using SeoToolkit.Umbraco.MetaFields.Core.Common.SeoFieldEditors; using SeoToolkit.Umbraco.MetaFields.Core.Constants; using SeoToolkit.Umbraco.MetaFields.Core.Interfaces.SeoField; +using Umbraco.Cms.Core.Composing; using Umbraco.Extensions; namespace SeoToolkit.Umbraco.MetaFields.Core.Models.SeoField; @@ -14,7 +14,7 @@ public class OpenGraphUrlField : SeoField public override string Title => "Open Graph Url"; public override string Alias => SeoFieldAliasConstants.OpenGraphUrl; public override string Description => "Open Graph Url for the content"; - public override string GroupAlias => SeoFieldGroupConstants.SocialMediaGroup; + public override string GroupAlias => SeoFieldGroupConstants.OpenGraphGroup; public override ISeoFieldEditor Editor { get; } public override ISeoFieldEditEditor EditEditor => new SeoTextBoxEditEditor(); diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphVideoField.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphVideoField.cs new file mode 100644 index 00000000..125bed6f --- /dev/null +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/OpenGraphVideoField.cs @@ -0,0 +1,68 @@ +using System; +using Microsoft.AspNetCore.Html; +using SeoToolkit.Umbraco.MetaFields.Core.Common.SeoFieldEditEditors; +using SeoToolkit.Umbraco.MetaFields.Core.Constants; +using SeoToolkit.Umbraco.MetaFields.Core.Interfaces.SeoField; +using SeoToolkit.Umbraco.MetaFields.Core.Models.SeoFieldEditors; +using Umbraco.Cms.Core.Composing; +using Umbraco.Cms.Core.Models.PublishedContent; +using Umbraco.Cms.Core.Web; +using Umbraco.Extensions; + +namespace SeoToolkit.Umbraco.MetaFields.Core.Models.SeoField +{ + [Weight(500)] + public class OpenGraphVideoField : SeoField + { + private readonly IUmbracoContextFactory _umbracoContextFactory; + public override string Title => "Open Graph Video"; + public override string Alias => SeoFieldAliasConstants.OpenGraphVideo; + public override string Description => "Video for Open Graph"; + public override string GroupAlias => SeoFieldGroupConstants.OpenGraphGroup; + + + public override ISeoFieldEditor Editor => new SeoFieldFieldsEditor(new[] { "Umbraco.MediaPicker3" }); + public override ISeoFieldEditEditor EditEditor => new SeoVideoEditEditor(_umbracoContextFactory); + + public OpenGraphVideoField(IUmbracoContextFactory umbracoContextFactory) + { + _umbracoContextFactory = umbracoContextFactory; + } + + protected override HtmlString Render(IPublishedContent value) + { + string url; + string height = string.Empty; + string width = string.Empty; + string type = string.Empty; + if (value is IPublishedContent media) + { + url = media.Url(mode: UrlMode.Absolute); + width = media.Value("umbracoWidth"); + height = media.Value("umbracoHeight"); + type = media.Value("umbracoExtension"); + } + else + { + url = value?.ToString(); + } + + var html = $""; + if (!string.IsNullOrEmpty(width)) + { + html += $""; + } + if (!string.IsNullOrEmpty(height)) + { + html += $""; + } + if (!string.IsNullOrEmpty(type)) + { + html += $""; + } + + + return new HtmlString(html); + } + } +} \ No newline at end of file diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/TwitterCardTypeField.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/TwitterCardTypeField.cs index d75c7f84..bf342db8 100644 --- a/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/TwitterCardTypeField.cs +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/TwitterCardTypeField.cs @@ -17,7 +17,7 @@ public class TwitterCardTypeField : SeoField public override string Title => "Twitter Card Type"; public override string Alias => SeoFieldAliasConstants.TwitterCardType; public override string Description => "Twitter Card Type for your page"; - public override string GroupAlias => SeoFieldGroupConstants.SocialMediaGroup; + public override string GroupAlias => SeoFieldGroupConstants.TwitterGroup; public override ISeoFieldEditor Editor { get; } public override ISeoFieldEditEditor EditEditor { get; } diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/TwitterCreatorField.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/TwitterCreatorField.cs index dc6aa905..347be959 100644 --- a/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/TwitterCreatorField.cs +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/TwitterCreatorField.cs @@ -14,7 +14,7 @@ public class TwitterCreatorField : SeoField public override string Title => "Twitter Creator"; public override string Alias => SeoFieldAliasConstants.TwitterCreator; public override string Description => "Twitter Creator for the content"; - public override string GroupAlias => SeoFieldGroupConstants.SocialMediaGroup; + public override string GroupAlias => SeoFieldGroupConstants.TwitterGroup; public override ISeoFieldEditor Editor { get; } public override ISeoFieldEditEditor EditEditor => new SeoTextBoxEditEditor(); diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/TwitterDescriptionField.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/TwitterDescriptionField.cs new file mode 100644 index 00000000..09a97d7d --- /dev/null +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/TwitterDescriptionField.cs @@ -0,0 +1,34 @@ +using System; +using Microsoft.AspNetCore.Html; +using SeoToolkit.Umbraco.MetaFields.Core.Common.SeoFieldEditEditors; +using SeoToolkit.Umbraco.MetaFields.Core.Constants; +using SeoToolkit.Umbraco.MetaFields.Core.Interfaces.SeoField; +using SeoToolkit.Umbraco.MetaFields.Core.Models.SeoFieldEditors; +using Umbraco.Cms.Core.Composing; + +namespace SeoToolkit.Umbraco.MetaFields.Core.Models.SeoField +{ + [Weight(400)] + public class TwitterDescriptionField : ISeoField + { + public string Title => "Twitter Description"; + public string Alias => SeoFieldAliasConstants.TwitterDescription; + public string Description => "Description for Twitter"; + public string GroupAlias => SeoFieldGroupConstants.TwitterGroup; + public Type FieldType => typeof(string); + + 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) + { + return new HtmlString($""); + } + } +} diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/TwitterImageField.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/TwitterImageField.cs new file mode 100644 index 00000000..9d3ea248 --- /dev/null +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/TwitterImageField.cs @@ -0,0 +1,60 @@ +using System; +using System.Linq; +using Microsoft.AspNetCore.Html; +using SeoToolkit.Umbraco.MetaFields.Core.Common.SeoFieldEditEditors; +using SeoToolkit.Umbraco.MetaFields.Core.Common.SeoFieldEditors; +using SeoToolkit.Umbraco.MetaFields.Core.Constants; +using SeoToolkit.Umbraco.MetaFields.Core.Interfaces.SeoField; +using SeoToolkit.Umbraco.MetaFields.Core.Models.SeoFieldEditors; +using Umbraco.Cms.Core.Composing; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Models.PublishedContent; +using Umbraco.Cms.Core.Routing; +using Umbraco.Cms.Core.Web; +using Umbraco.Extensions; + +namespace SeoToolkit.Umbraco.MetaFields.Core.Models.SeoField +{ + [Weight(500)] + public class TwitterImageField : SeoField + { + private readonly IUmbracoContextFactory _umbracoContextFactory; + public override string Title => "Twitter Image"; + public override string Alias => SeoFieldAliasConstants.TwitterImage; + public override string Description => "Image for Twitter"; + public override string GroupAlias => SeoFieldGroupConstants.TwitterGroup; + + + public override ISeoFieldEditor Editor => new SeoFieldFieldsEditor(new[] { "Umbraco.MediaPicker", "Umbraco.MediaPicker3" }); + public override ISeoFieldEditEditor EditEditor => new SeoImageEditEditor(_umbracoContextFactory); + + public TwitterImageField(IUmbracoContextFactory umbracoContextFactory) + { + _umbracoContextFactory = umbracoContextFactory; + + + } + + + protected override HtmlString Render(IPublishedContent value) + { + string url; + + if (value is { } media) + { + url = media.Url(mode: UrlMode.Absolute); + + } + else + { + url = value?.ToString(); + } + + var html = $""; + + + + return new HtmlString(html); + } + } +} \ No newline at end of file diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/TwitterSiteField.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/TwitterSiteField.cs index b821bfe7..3f9f4959 100644 --- a/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/TwitterSiteField.cs +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/TwitterSiteField.cs @@ -14,7 +14,7 @@ public class TwitterSiteField : SeoField public override string Title => "Twitter Site"; public override string Alias => SeoFieldAliasConstants.TwitterSite; public override string Description => "Twitter Site for the content"; - public override string GroupAlias => SeoFieldGroupConstants.SocialMediaGroup; + public override string GroupAlias => SeoFieldGroupConstants.TwitterGroup; public override ISeoFieldEditor Editor { get; } public override ISeoFieldEditEditor EditEditor => new SeoTextBoxEditEditor(); diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/TwitterTitleField.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/TwitterTitleField.cs new file mode 100644 index 00000000..1276a0bc --- /dev/null +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/TwitterTitleField.cs @@ -0,0 +1,34 @@ +using Microsoft.AspNetCore.Html; +using Umbraco.Cms.Core.Composing; +using SeoToolkit.Umbraco.MetaFields.Core.Common.SeoFieldEditEditors; +using SeoToolkit.Umbraco.MetaFields.Core.Common.SeoFieldEditors; +using SeoToolkit.Umbraco.MetaFields.Core.Constants; +using SeoToolkit.Umbraco.MetaFields.Core.Interfaces.SeoField; +using Umbraco.Extensions; + +namespace SeoToolkit.Umbraco.MetaFields.Core.Models.SeoField; + +[Weight(602)] +public class TwitterTitleField : SeoField +{ + public override string Title => "Twitter Title"; + public override string Alias => SeoFieldAliasConstants.TwitterTitle; + public override string Description => "Twitter Name for the content"; + public override string GroupAlias => SeoFieldGroupConstants.TwitterGroup; + public override ISeoFieldEditor Editor { get; } + public override ISeoFieldEditEditor EditEditor => new SeoTextBoxEditEditor(); + + public TwitterTitleField() + { + var propertyEditor = new SeoFieldPropertyEditor("textbox"); + propertyEditor.SetExtraInformation("Provide the Title of Page to show on Twitter"); + propertyEditor.SetDefaultValue("%CurrentPageName%"); + + Editor = propertyEditor; + } + + protected override HtmlString Render(string value) + { + return new HtmlString(value.IsNullOrWhiteSpace() ? string.Empty : $""); + } +} \ No newline at end of file diff --git a/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/TwitterUrlField.cs b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/TwitterUrlField.cs new file mode 100644 index 00000000..fab1b711 --- /dev/null +++ b/src/SeoToolkit.Umbraco.MetaFields.Core/Models/SeoField/TwitterUrlField.cs @@ -0,0 +1,34 @@ +using Microsoft.AspNetCore.Html; +using SeoToolkit.Umbraco.MetaFields.Core.Common.SeoFieldEditEditors; +using SeoToolkit.Umbraco.MetaFields.Core.Common.SeoFieldEditors; +using SeoToolkit.Umbraco.MetaFields.Core.Constants; +using SeoToolkit.Umbraco.MetaFields.Core.Interfaces.SeoField; +using Umbraco.Cms.Core.Composing; +using Umbraco.Extensions; + +namespace SeoToolkit.Umbraco.MetaFields.Core.Models.SeoField; + +[Weight(600)] +public class TwitterUrlField : SeoField +{ + public override string Title => "Twitter Url"; + public override string Alias => SeoFieldAliasConstants.TwitterUrl; + public override string Description => "Twitter Url for the content"; + public override string GroupAlias => SeoFieldGroupConstants.TwitterGroup; + public override ISeoFieldEditor Editor { get; } + public override ISeoFieldEditEditor EditEditor => new SeoTextBoxEditEditor(); + + public TwitterUrlField() + { + var propertyEditor = new SeoFieldPropertyEditor("textbox"); + propertyEditor.SetExtraInformation("You can use %CurrentUrl% to display the URL of the current item"); + propertyEditor.SetDefaultValue("%CurrentUrl%"); + + Editor = propertyEditor; + } + + protected override HtmlString Render(string value) + { + return new HtmlString(value.IsNullOrWhiteSpace() ? null : $""); + } +} \ No newline at end of file diff --git a/src/SeoToolkit.Umbraco.MetaFields/Composer.cs b/src/SeoToolkit.Umbraco.MetaFields/Composer.cs index 61984de4..655e7500 100644 --- a/src/SeoToolkit.Umbraco.MetaFields/Composer.cs +++ b/src/SeoToolkit.Umbraco.MetaFields/Composer.cs @@ -30,6 +30,8 @@ public void Compose(IUmbracoBuilder builder) builder.WithCollectionBuilder() .Append() + .Append() + .Append() .Append() .Append(); }