Skip to content
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

NEST-536: Move Google Tag into HE so it's available regardless of theme #176

Merged
merged 18 commits into from
Aug 23, 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
@@ -0,0 +1,50 @@
using Fluid;
using Fluid.Ast;
using Fluid.Values;
using Lombiq.HelpfulLibraries.OrchardCore.Liquid;
using OrchardCore.DisplayManagement.Liquid.Tags;
using System.Collections.Generic;
using System.IO;
using System.Text.Encodings.Web;
using System.Threading.Tasks;

namespace Lombiq.HelpfulExtensions.Extensions.GoogleTag;

public class GoogleTagLiquidParserTag : ILiquidParserTag
{
public async ValueTask<Completion> WriteToAsync(
IReadOnlyList<FilterArgument> argumentsList,
TextWriter writer,
TextEncoder encoder,
TemplateContext context)
{
var arguments = new List<FilterArgument>
{
new(null, new LiteralExpression(new StringValue(GoogleTagViewModel.ShapeType))),
};

foreach (var argument in argumentsList)
{
if (argument.Name == "property_id")
{
await AddStringAsync(arguments, nameof(GoogleTagViewModel.GoogleTagPropertyId), argument, context);
}
else if (argument.Name == "cookie_domain")
{
await AddStringAsync(arguments, nameof(GoogleTagViewModel.CookieDomain), argument, context);
}
}

return await ShapeTag.WriteToAsync(arguments, writer, encoder, context);
}

private static async Task AddStringAsync(
List<FilterArgument> arguments,
string newName,
FilterArgument argument,
TemplateContext context)
{
var newValue = await argument.Expression.EvaluateAsync(context);
arguments.Add(new(newName, new LiteralExpression(newValue)));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using Lombiq.HelpfulLibraries.OrchardCore.TagHelpers;
using Microsoft.AspNetCore.Razor.TagHelpers;
using OrchardCore.DisplayManagement;
using System.Threading.Tasks;

namespace Lombiq.HelpfulExtensions.Extensions.GoogleTag;

[HtmlTargetElement("google-tag")]
public class GoogleTagTagHelper : ShapeTagHelperBase<GoogleTagViewModel>
{
[HtmlAttributeName("property-id")]
public string PropertyId { get; set; }

[HtmlAttributeName("cookie-domain")]
public string CookieDomain { get; set; }

public GoogleTagTagHelper(IDisplayHelper displayHelper, IShapeFactory shapeFactory)
: base(displayHelper, shapeFactory)
{
}

protected override string ShapeType => GoogleTagViewModel.ShapeType;

protected override ValueTask<GoogleTagViewModel> GetViewModelAsync(TagHelperContext context, TagHelperOutput output) =>
ValueTask.FromResult(new GoogleTagViewModel(PropertyId, CookieDomain));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using OrchardCore.DisplayManagement.Views;

namespace Lombiq.HelpfulExtensions.Extensions.GoogleTag;

public class GoogleTagViewModel : ShapeViewModel
{
public const string ShapeType = "GoogleTag";

public string GoogleTagPropertyId { get; set; }
public string CookieDomain { get; set; }

public GoogleTagViewModel() => Metadata.Type = ShapeType;

public GoogleTagViewModel(string googleTagPropertyId, string cookieDomain)
: this()
{
GoogleTagPropertyId = googleTagPropertyId;
CookieDomain = cookieDomain;
}
}
14 changes: 14 additions & 0 deletions Lombiq.HelpfulExtensions/Extensions/GoogleTag/Startup.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using Microsoft.Extensions.DependencyInjection;
using OrchardCore.Modules;

namespace Lombiq.HelpfulExtensions.Extensions.GoogleTag;

[Feature(FeatureIds.GoogleTag)]
public class Startup : StartupBase
{
public override void ConfigureServices(IServiceCollection services)
{
services.AddTagHelpers<GoogleTagTagHelper>();
services.AddLiquidParserTag<GoogleTagLiquidParserTag>("google_tag");
}
}
1 change: 1 addition & 0 deletions Lombiq.HelpfulExtensions/FeatureIds.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ public static class FeatureIds
public const string Workflows = FeatureIdPrefix + nameof(Workflows);
public const string Trumbowyg = FeatureIdPrefix + nameof(Trumbowyg);
public const string ResetPasswordActivity = Workflows + "." + nameof(ResetPasswordActivity);
public const string GoogleTag = FeatureIdPrefix + nameof(GoogleTag);
Piedone marked this conversation as resolved.
Show resolved Hide resolved
}
24 changes: 12 additions & 12 deletions Lombiq.HelpfulExtensions/Lombiq.HelpfulExtensions.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,18 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="OrchardCore.Autoroute" Version="2.0.0-preview-18312" />
<PackageReference Include="OrchardCore.ContentFields" Version="2.0.0-preview-18312" />
<PackageReference Include="OrchardCore.Contents" Version="2.0.0-preview-18312" />
<PackageReference Include="OrchardCore.Flows" Version="2.0.0-preview-18312" />
<PackageReference Include="OrchardCore.Html" Version="2.0.0-preview-18312" />
<PackageReference Include="OrchardCore.Lists" Version="2.0.0-preview-18312" />
<PackageReference Include="OrchardCore.Liquid.Abstractions" Version="2.0.0-preview-18312" />
<PackageReference Include="OrchardCore.Markdown" Version="2.0.0-preview-18312" />
<PackageReference Include="OrchardCore.MetaWeblog.Abstractions" Version="2.0.0-preview-18312" />
<PackageReference Include="OrchardCore.Module.Targets" Version="2.0.0-preview-18312" />
<PackageReference Include="OrchardCore.Rules.Abstractions" Version="2.0.0-preview-18312" />
<PackageReference Include="OrchardCore.Workflows" Version="2.0.0-preview-18312" />
<PackageReference Include="OrchardCore.Autoroute" Version="2.0.0-preview-18315" />
<PackageReference Include="OrchardCore.ContentFields" Version="2.0.0-preview-18315" />
<PackageReference Include="OrchardCore.Contents" Version="2.0.0-preview-18315" />
<PackageReference Include="OrchardCore.Flows" Version="2.0.0-preview-18315" />
<PackageReference Include="OrchardCore.Html" Version="2.0.0-preview-18315" />
<PackageReference Include="OrchardCore.Lists" Version="2.0.0-preview-18315" />
<PackageReference Include="OrchardCore.Liquid" Version="2.0.0-preview-18315" />
<PackageReference Include="OrchardCore.Markdown" Version="2.0.0-preview-18315" />
<PackageReference Include="OrchardCore.MetaWeblog.Abstractions" Version="2.0.0-preview-18315" />
<PackageReference Include="OrchardCore.Module.Targets" Version="2.0.0-preview-18315" />
<PackageReference Include="OrchardCore.Rules.Abstractions" Version="2.0.0-preview-18315" />
<PackageReference Include="OrchardCore.Workflows" Version="2.0.0-preview-18315" />
<PackageReference Include="Scrutor" Version="4.2.2" />
</ItemGroup>

Expand Down
7 changes: 7 additions & 0 deletions Lombiq.HelpfulExtensions/Manifest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -146,3 +146,10 @@
Category = "Content",
Description = "Adds option for inserting code snippets in Trumbowyg editor."
)]

[assembly: Feature(
Id = GoogleTag,
Name = "Lombiq Helpful Extensions - Google Tag",
Category = "Content",
Description = "Adds a shape along with Razor and Liquid tag helpers for Google Analytics."
)]
38 changes: 38 additions & 0 deletions Lombiq.HelpfulExtensions/Views/GoogleTag.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
@model dynamic

@using Lombiq.HelpfulLibraries.OrchardCore.Security
@using Microsoft.AspNetCore.Http.Features;
@using Microsoft.Extensions.Hosting;
@using Lombiq.HelpfulExtensions.Extensions.GoogleTag

@inject IHostEnvironment HostEnvironment

@{
var trackingConsentFeature = ViewContext.HttpContext.Features.Get<ITrackingConsentFeature>();
}

@if (HostEnvironment.IsProduction() && trackingConsentFeature is not { CanTrack: false })
{
GoogleAnalyticsContentSecurityPolicyProvider.EnableForCurrentRequest(Context);

var viewModel = Model as GoogleTagViewModel ?? new GoogleTagViewModel
{
GoogleTagPropertyId = Model.GoogleTagPropertyId,
CookieDomain = Model.CookieDomain,
};
var cookieDomain = string.Empty;

if (!string.IsNullOrEmpty(viewModel.CookieDomain))
{
cookieDomain = $", {{'cookie_domain': '{viewModel.CookieDomain}' }}";
}

<script async src="https://www.googletagmanager.com/gtag/js?id=@viewModel.GoogleTagPropertyId"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }
gtag('js', new Date());

gtag('config', '@viewModel.GoogleTagPropertyId'@Html.Raw(cookieDomain))
</script>
}
6 changes: 6 additions & 0 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,12 @@ builder.WhenContentTypeEditor("BlogPost").RegisterFootScript(Lombiq.HelpfulExten
builder.WhenContentTypeEditor("BlogPost").RegisterStylesheet(Lombiq.HelpfulExtensions.Constants.ResourceNames.TrumbowygHighlight);
```

### Google Tag

Adds a shape along with Razor and Liquid tag helpers for Google Analytics, using <https://tagmanager.google.com/>.

You can use the `<google-tag property-id="..." cookie-domain="auto">` Razor tag helper in _cshtml_ files or the `{% google_tag property_id: "...", cookie_domain: "auto" %}` parser tag in Liquid.

## Contributing and support

Bug reports, feature requests, comments, questions, code contributions and love letters are warmly welcome. You can send them to us via GitHub issues and pull requests. Please adhere to our [open-source guidelines](https://lombiq.com/open-source-guidelines) while doing so.
Expand Down