using System.Web;
using Cysharp.Text;
using OliverBooth.Common.Data.Blog;
using OliverBooth.Common.Data.Web;
using OliverBooth.Common.Services;
namespace OliverBooth.Extensions;
///
/// Provides helper methods for generating HTML tags
///
public static class HtmlUtility
{
///
/// Creates <meta> embed tags by pulling data from the specified blog post.
///
/// The blog post whose metadata should be retrieved.
/// The injected by the page.
/// A string containing a collection of <meta> embed tags.
///
/// is .
/// -or-
/// is .
///
public static string CreateMetaTagsFromPost(IBlogPost post, IBlogPostService blogPostService)
{
if (post is null)
{
throw new ArgumentNullException(nameof(post));
}
if (blogPostService is null)
{
throw new ArgumentNullException(nameof(blogPostService));
}
string excerpt = blogPostService.RenderExcerpt(post, out _);
var tags = new Dictionary
{
["title"] = post.Title,
["description"] = excerpt,
["author"] = post.Author.DisplayName
};
return CreateMetaTags(tags);
}
///
/// Creates <meta> embed tags by pulling data from the specified article.
///
/// The article whose metadata should be retrieved.
/// The injected by the page.
/// A string containing a collection of <meta> embed tags.
///
/// is .
/// -or-
/// is .
///
public static string CreateMetaTagsFromTutorialArticle(ITutorialArticle article, ITutorialService tutorialService)
{
if (article is null)
{
throw new ArgumentNullException(nameof(article));
}
if (tutorialService is null)
{
throw new ArgumentNullException(nameof(tutorialService));
}
string excerpt = tutorialService.RenderExcerpt(article, out _);
var tags = new Dictionary
{
["title"] = article.Title,
["description"] = excerpt,
["author"] = "Oliver Booth" // TODO add article author support?
};
return CreateMetaTags(tags);
}
///
/// Creates <meta> embed tags by pulling data from the specified dictionary.
///
///
/// A dictionary containing the tag values. This dictionary should be in the form:
///
///
///
/// Key
/// Description
///
///
/// -
/// description
///
/// The value to apply to the description, og:description, and twitter:description, tags.
///
///
///
/// -
/// author
/// The value to apply to the og:site_name, and twitter:creator, tags.
///
///
/// -
/// title
///
/// The value to apply to the title, og:title, and twitter:title, tags.
///
///
///
///
/// Any other values contained with the dictionary are ignored.
///
/// A string containing a collection of <meta> embed tags.
/// is .
public static string CreateMetaTags(IReadOnlyDictionary tags)
{
if (tags is null)
{
throw new ArgumentNullException(nameof(tags));
}
using Utf8ValueStringBuilder builder = ZString.CreateUtf8StringBuilder();
builder.AppendLine("""""");
if (tags.TryGetValue("description", out string? description))
{
description = HttpUtility.HtmlEncode(description);
builder.AppendLine($"""""");
builder.AppendLine($"""""");
builder.AppendLine($"""""");
}
if (tags.TryGetValue("author", out string? author))
{
author = HttpUtility.HtmlEncode(author);
builder.AppendLine($"""""");
builder.AppendLine($"""""");
}
if (tags.TryGetValue("title", out string? title))
{
title = HttpUtility.HtmlEncode(title);
builder.AppendLine($"""""");
builder.AppendLine($"""""");
builder.AppendLine($"""""");
}
return builder.ToString();
}
}