-
Notifications
You must be signed in to change notification settings - Fork 4
Feature/tag helpers #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Nhawdge
wants to merge
4
commits into
main
Choose a base branch
from
feature/TagHelpers
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| using Blend.Optimizely; | ||
| using EPiServer.ServiceLocation; | ||
| using Microsoft.AspNetCore.Razor.TagHelpers; | ||
|
|
||
| namespace Blend.Optimizely.TagHelpers | ||
| { | ||
| [HtmlTargetElement("a", Attributes = "content-link")] | ||
| public class AnchorTagHelper : TagHelper | ||
| { | ||
| private Injected<LinkResolverService> LinkResolver { get; } | ||
|
|
||
| /// <summary> | ||
| /// Some kind of link that can be resolved via Optimizely. This includes: | ||
| /// IResolvable for special cases | ||
| /// IContent objects | ||
| /// Url objects | ||
| /// LinkItem objects | ||
| /// ContentReference objects | ||
| /// </summary> | ||
| [HtmlAttributeName("content-link")] | ||
| public object ContentLink { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// How should the anchor tag be handle when there is no valid href or the condition is false. | ||
| /// Options are: | ||
| /// None, ConvertLinkToSpan, SuppressOutput, KeepInnerContent | ||
| /// </summary> | ||
| [HtmlAttributeName("link-options")] | ||
| public LinkOptions LinkOptions { get; set; } | ||
|
|
||
| [HtmlAttributeName("fallback-option")] | ||
| public AnchorFallbackOptions FallbackOption { get; set; } | ||
|
|
||
| /// <summary> | ||
| /// Only output an anchor tag with href when condition is true and a valid link exists. Default is true | ||
| /// </summary> | ||
| [HtmlAttributeName("condition")] | ||
| public bool Condition { get; set; } = true; | ||
|
|
||
| public override void Process(TagHelperContext context, TagHelperOutput output) | ||
| { | ||
| if (context is null || output is null) | ||
| return; | ||
|
|
||
| var resolvedLink = LinkResolver.Service.TryResolveLink(ContentLink, LinkOptions); | ||
| if (resolvedLink is not null && resolvedLink.Href.HasValue() && Condition) | ||
| { | ||
| output.Attributes.SetAttribute("href", resolvedLink.Href); | ||
|
|
||
| if (resolvedLink.Target.HasValue() && !context.AllAttributes.TryGetAttribute("target", out _)) | ||
| output.Attributes.SetAttribute("target", resolvedLink.Target); | ||
| } | ||
| else if (FallbackOption is AnchorFallbackOptions.ConvertLinkToSpan) | ||
| { | ||
| output.TagName = "span"; | ||
| } | ||
| else if (FallbackOption is AnchorFallbackOptions.SuppressOutput) | ||
| { | ||
| output.SuppressOutput(); | ||
| return; | ||
| } | ||
| else if (FallbackOption is AnchorFallbackOptions.KeepInnerContent) | ||
| { | ||
| output.TagName = string.Empty; | ||
| return; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| public enum AnchorFallbackOptions | ||
| { | ||
| None = 0, | ||
|
|
||
| /// <summary> | ||
| /// If url is blank, convert the wrapping a tag to a span | ||
| /// </summary> | ||
| ConvertLinkToSpan = 1, | ||
|
|
||
| /// <summary> | ||
| /// If url is blank, suppress output | ||
| /// </summary> | ||
| SuppressOutput = 2, | ||
|
|
||
| /// <summary> | ||
| /// If url is blank, remove wrapping tag | ||
| /// </summary> | ||
| KeepInnerContent = 3 | ||
| } | ||
| } |
36 changes: 36 additions & 0 deletions
36
src/Blend.Optimizely/TagHelpers/ConditionalWrapperHelper.cs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| using Microsoft.AspNetCore.Razor.TagHelpers; | ||
| using System; | ||
| using System.Collections.Generic; | ||
| using System.Linq; | ||
| using System.Text; | ||
| using System.Threading.Tasks; | ||
|
|
||
| namespace Blend.Optimizely.TagHelpers | ||
| { | ||
| [HtmlTargetElement("*", Attributes = "wrap-if")] | ||
| [HtmlTargetElement("*", Attributes = "suppress-if")] | ||
| public class ConditionalWrapperHelper : TagHelper | ||
| { | ||
| [HtmlAttributeName("wrap-if")] | ||
| public bool WrapIfCondition { get; set; } | ||
|
|
||
| [HtmlAttributeName("suppress-if")] | ||
| public bool SuppressIfCondition { get; set; } | ||
|
|
||
|
|
||
| [HtmlAttributeName("link-options")] | ||
| public LinkOptions LinkOptions { get; set; } | ||
|
|
||
| public override void Process(TagHelperContext context, TagHelperOutput output) | ||
| { | ||
| if (SuppressIfCondition) | ||
| { | ||
| output.SuppressOutput(); | ||
| } | ||
| if (!WrapIfCondition) | ||
| { | ||
| output.TagName = null; | ||
| } | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| using EPiServer.Core; | ||
| using System.Collections.Generic; | ||
|
|
||
| namespace Blend.Optimizely.TagHelpers | ||
| { | ||
| internal interface IImageFile :IContent | ||
| { | ||
| public int Width { get; set; } | ||
| public int Height { get; set; } | ||
|
|
||
| public string GetAltText(); | ||
|
|
||
| public IEnumerable<int> ImageOptions(); | ||
|
|
||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| using EPiServer; | ||
| using EPiServer.Core; | ||
| using EPiServer.ServiceLocation; | ||
| using Microsoft.AspNetCore.Razor.TagHelpers; | ||
| using System.Collections.Generic; | ||
| using System.Linq; | ||
|
|
||
| namespace Blend.Optimizely.TagHelpers | ||
| { | ||
| [HtmlTargetElement("Image", Attributes = "src", TagStructure = TagStructure.WithoutEndTag)] | ||
| public class ImageHelper : TagHelper | ||
| { | ||
| public ContentReference? src { get; set; } | ||
|
|
||
| [HtmlAttributeName("eager-loading")] | ||
| public bool EagerLoading { get; set; } | ||
| public override void Process(TagHelperContext context, TagHelperOutput output) | ||
| { | ||
| if (!src.HasValue() && output != null) | ||
| { | ||
| output.SuppressOutput(); | ||
| return; | ||
| } | ||
|
|
||
| var imgUrl = src.ResolveUrl(); | ||
| if (!imgUrl.HasValue()) | ||
| { | ||
| output.SuppressOutput(); | ||
| return; | ||
| } | ||
|
|
||
| var imageVariations = new List<string>(); | ||
|
|
||
| var loader = ServiceLocator.Current.GetInstance<IContentLoader>(); | ||
| if (loader.TryGet<IImageFile>(src, out var image)) | ||
| { | ||
| output.Attributes.SetAttribute("alt", image.GetAltText()); | ||
|
|
||
| if (image.Width > 0) | ||
| output.Attributes.SetAttribute("width", image.Width); | ||
|
|
||
| if (image.Height > 0) | ||
| output.Attributes.SetAttribute("height", image.Height); | ||
|
|
||
| imageVariations = image.ImageOptions().Where(x => x != image.Width).Select(x => | ||
| { | ||
| var url = new UrlBuilder(imgUrl); | ||
| url.QueryCollection.Add("width", x.ToString()); | ||
| return (string)url + $" {x}w"; | ||
| }).ToList(); | ||
|
|
||
| if (imageVariations.HasValue()) | ||
| { | ||
| imageVariations.Add($"{imgUrl} {image.Width}w"); | ||
| output.Attributes.SetAttribute("srcset", string.Join($", ", imageVariations)); | ||
| output.Attributes.SetAttribute("sizes", "100vw"); | ||
| } | ||
| } | ||
|
|
||
| output.TagName = "img"; | ||
| output.TagMode = TagMode.SelfClosing; | ||
| output.Attributes.SetAttribute("src", imgUrl); | ||
|
|
||
| if (!EagerLoading) | ||
| output.Attributes.SetAttribute("loading", "lazy"); | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| using EPiServer; | ||
| using EPiServer.Core; | ||
| using Microsoft.AspNetCore.Razor.TagHelpers; | ||
| using System.Linq; | ||
|
|
||
| namespace Blend.Optimizely.TagHelpers | ||
| { | ||
|
|
||
| [HtmlTargetElement("Source", Attributes = "srcset")] | ||
| public class SourceHelper : TagHelper | ||
| { | ||
| public ContentReference? src { get; set; } | ||
|
|
||
| public bool EagerLoading { get; set; } | ||
| public override void Process(TagHelperContext context, TagHelperOutput output) | ||
| { | ||
| if (!src.HasValue() && output != null) | ||
| { | ||
| output.SuppressOutput(); | ||
| return; | ||
| } | ||
|
|
||
| var image = src.Get<IImageFile>(); // NOTE: This is likely to be a breaking change - Switching from `ImageFile` to `IImageFile` | ||
| var imgUrl = src.ResolveUrl(); | ||
|
|
||
| if (image == null || !imgUrl.HasValue()) | ||
| { | ||
| output.SuppressOutput(); | ||
| return; | ||
| } | ||
|
|
||
| output.TagName = "img"; | ||
| output.TagMode = TagMode.SelfClosing; | ||
| output.Attributes.SetAttribute("src", imgUrl); | ||
| output.Attributes.SetAttribute("alt", image.GetAltText()); // NOTE: This is likely to be a breaking change - Switching from `ContentReference` to `IImageFile` | ||
|
|
||
| if (image.Width > 0) | ||
| output.Attributes.SetAttribute("width", image.Width); | ||
|
|
||
| if (image.Height > 0) | ||
| output.Attributes.SetAttribute("height", image.Height); | ||
|
|
||
| var imageVariations = image.ImageOptions().Where(x => x != image.Width).Select(x => | ||
| { | ||
| var url = new UrlBuilder(imgUrl); | ||
| url.QueryCollection.Add("width", x.ToString()); | ||
| return (string)url + $" {x}w"; | ||
| }).ToList(); | ||
|
|
||
| if (imageVariations.HasValue()) | ||
| { | ||
| imageVariations.Add($"{imgUrl} {image.Width}w"); | ||
| output.Attributes.SetAttribute("srcset", string.Join($", ", imageVariations)); | ||
| output.Attributes.SetAttribute("sizes", "100vw"); | ||
| } | ||
|
|
||
| if (!EagerLoading) | ||
| output.Attributes.SetAttribute("loading", "lazy"); | ||
| } | ||
| } | ||
| } | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Nhawdge I don't know that this tag helper fits our use cases. We should chat about this and maybe include a FE dev.