Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Expose properties of ITrackingConsentFeature and cookie policy in Liquid #17148

Merged
merged 5 commits into from
Dec 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ public void Configure(TemplateOptions options)

options.Scope.SetValue("HttpContext", new HttpContextValue());

options.Scope.SetValue("TrackingConsent", new TrackingConsentValue());

options.MemberAccessStrategy.Register<FormCollection, FluidValue>((forms, name) =>
{
if (name == "Keys")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ internal sealed class HttpRequestValue : FluidValue
{
public override FluidValues Type => FluidValues.Object;

/// <summary>
/// Creates a new instance of a <see cref="HttpRequestValue"/> for the specified HTTP request.
/// </summary>
public override bool Equals(FluidValue other)
{
if (other is null)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
using Fluid;
using Fluid.Values;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using OrchardCore.Liquid;

#nullable enable

namespace OrchardCore.DisplayManagement.Liquid.Values;

/// <summary>
/// Exposes <see href="ITrackingConsentFeature" />properties to Liquid.
/// </summary>
/// <remarks>
/// Exposes the following properties:
/// - CanTrack
/// - HasConsent
/// - IsConsentNeeded
/// - CookieName
/// - CookieValue
/// </remarks>
internal sealed class TrackingConsentValue : FluidValue
{
public override FluidValues Type => FluidValues.Object;

public override bool Equals(FluidValue other)
=> other is TrackingConsentValue;

public override bool ToBooleanValue() => true;

public override decimal ToNumberValue() => 0;

public override object ToObjectValue() => null!;

public override string ToStringValue() => "TrackingConsent";

protected override FluidValue GetValue(string name, TemplateContext context)
{
var feature = GetTrackingFeature(context);

if (feature is null)
{
return NilValue.Instance;
}

return name switch
{
nameof(ITrackingConsentFeature.CanTrack) => BooleanValue.Create(feature.CanTrack),
nameof(ITrackingConsentFeature.HasConsent) => BooleanValue.Create(feature.HasConsent),
nameof(ITrackingConsentFeature.IsConsentNeeded) => BooleanValue.Create(feature.IsConsentNeeded),
"CookieName" => new StringValue(GetCookiePolicyOptions(context)?.ConsentCookie?.Name ?? string.Empty),
"CookieValue" => new StringValue(GetCookiePolicyOptions(context)?.ConsentCookieValue ?? string.Empty),
_ => NilValue.Instance
};
}

private static ITrackingConsentFeature? GetTrackingFeature(TemplateContext context)
{
var ctx = context as LiquidTemplateContext
?? throw new InvalidOperationException($"An implementation of '{nameof(LiquidTemplateContext)}' is required");

var httpContext = ctx.Services.GetRequiredService<IHttpContextAccessor>().HttpContext;

return httpContext?.Features.Get<ITrackingConsentFeature>();
}

private static CookiePolicyOptions? GetCookiePolicyOptions(TemplateContext context)
{
var ctx = context as LiquidTemplateContext
?? throw new InvalidOperationException($"An implementation of '{nameof(LiquidTemplateContext)}' is required");

return ctx.Services.GetService<IOptions<CookiePolicyOptions>>()?.Value;
}
}
30 changes: 30 additions & 0 deletions src/docs/reference/modules/Liquid/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,36 @@ Removes key from HttpContext.Items collection

`{% httpcontext_remove_items "Item1" %}`

### TrackingConsent

Represents the tracking consent feature of the current request.

The following properties are available on the `TrackingConsent` object.

| Property | Example | Description |
| --------- | ---- |------------ |
| `CanTrack` | `true` | Indicates if tracking is allowed. |
| `HasConsent` | `true` | Indicates if the user has given consent for tracking. |
| `IsConsentNeeded` | `false` | Indicates if consent is needed for tracking. |
| `CookieName` | `ConsentCookie` | The name of the consent cookie. |
| `CookieValue` | `true` | The value of the consent cookie. |

#### Usage

Here is an example of how to use the `TrackingConsent` object in a Liquid template:

```liquid
{% if TrackingConsent.CanTrack %}
{% if TrackingConsent.HasConsent %}
<p>Tracking is allowed and the user has given consent.</p>
{% else %}
<p>Tracking is allowed but the user has not given consent.</p>
{% endif %}
{% else %}
<p>Tracking is not allowed.</p>
{% endif %}
```

## Shape Filters

These filters let you create and filter shapes.
Expand Down
Loading