-
Notifications
You must be signed in to change notification settings - Fork 969
enable page plugin contributions for public routes and enhance GTM plugin #156
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
base: main
Are you sure you want to change the base?
Changes from all commits
ea71c1d
42ba0db
875bd81
7eb084f
0455a26
3af9114
3efac48
e0c1dbb
436640e
fc07fbf
1d182e2
7933182
f146bd9
49d5ee1
05f4cb4
cf09f82
a68a9d8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| { | ||
| "name": "@emdash-cms/plugin-google-tag-manager", | ||
| "version": "0.1.0", | ||
| "description": "Google Tag Manager plugin for EmDash CMS", | ||
| "type": "module", | ||
| "main": "src/index.ts", | ||
| "exports": { | ||
| ".": "./src/index.ts", | ||
| "./sandbox": "./src/sandbox-entry.ts" | ||
| }, | ||
| "files": [ | ||
| "src" | ||
| ], | ||
| "keywords": [ | ||
| "emdash", | ||
| "cms", | ||
| "plugin", | ||
| "gtm", | ||
| "google tag manager", | ||
| "analytics" | ||
| ], | ||
| "author": "Your Name", | ||
| "license": "MIT", | ||
| "dependencies": {}, | ||
| "peerDependencies": { | ||
| "emdash": "workspace:*" | ||
| }, | ||
| "devDependencies": {}, | ||
| "scripts": { | ||
| "typecheck": "tsgo --noEmit" | ||
| }, | ||
| "optionalDependencies": {}, | ||
| "repository": { | ||
| "type": "git", | ||
| "url": "git+https://github.com/emdash-cms/emdash.git", | ||
| "directory": "packages/plugins/google-tag-manager" | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,13 @@ | ||||||
| import type { PluginDescriptor } from "emdash"; | ||||||
|
|
||||||
| export function googleTagManagerPlugin(): PluginDescriptor { | ||||||
| return { | ||||||
| id: "google-tag-manager", | ||||||
| version: "0.1.0", | ||||||
| format: "standard", | ||||||
| entrypoint: "@emdash-cms/plugin-google-tag-manager/sandbox", | ||||||
| options: {}, | ||||||
| capabilities: ["page:inject"], | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [needs fixing] The plugin declares the deprecated capability
Suggested change
|
||||||
| adminPages: [{ path: "/settings", label: "Google Tag Manager", icon: "activity" }], | ||||||
| }; | ||||||
| } | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,135 @@ | ||
| import { definePlugin } from "emdash"; | ||
| import type { PluginContext } from "emdash"; | ||
|
|
||
| export default definePlugin({ | ||
| hooks: { | ||
| "page:fragments": async (_event: unknown, ctx: PluginContext) => { | ||
| const containerId = await ctx.kv.get<string>("settings:gtmContainerId"); | ||
| if (!containerId) return null; | ||
|
|
||
| const dataLayerName = (await ctx.kv.get<string>("settings:gtmDataLayerName")) || "dataLayer"; | ||
| const gtmScriptUrl = | ||
| (await ctx.kv.get<string>("settings:gtmScriptUrl")) || | ||
| "https://www.googletagmanager.com/gtm.js"; | ||
| const gtmNoScriptUrl = | ||
| (await ctx.kv.get<string>("settings:gtmNoScriptUrl")) || | ||
| "https://www.googletagmanager.com/ns.html"; | ||
|
|
||
| return [ | ||
| { | ||
| kind: "inline-script", | ||
| placement: "head", | ||
| code: `(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': | ||
| new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], | ||
| j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= | ||
| '${gtmScriptUrl}?id='+i+dl;f.parentNode.insertBefore(j,f); | ||
| })(window,document,'script','${dataLayerName}','${containerId}');`, | ||
|
Comment on lines
+22
to
+26
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [needs fixing] The |
||
| }, | ||
| { | ||
| kind: "html", | ||
| placement: "body:start", | ||
| html: `<noscript><iframe src="${gtmNoScriptUrl}?id=${containerId}" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>`, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [needs fixing] The |
||
| }, | ||
| ]; | ||
| }, | ||
| }, | ||
|
|
||
| routes: { | ||
| admin: { | ||
| handler: async ( | ||
| routeCtx: { input: unknown; request: { url: string } }, | ||
| ctx: PluginContext, | ||
| ) => { | ||
| const interaction = routeCtx.input as { | ||
| type: string; | ||
| page?: string; | ||
| action_id?: string; | ||
| values?: Record<string, string>; | ||
| }; | ||
|
|
||
| if (interaction.type === "page_load" && interaction.page === "/settings") { | ||
| return buildSettingsBlocks(ctx); | ||
| } | ||
|
|
||
| if (interaction.type === "form_submit" && interaction.action_id === "save_gtm") { | ||
| const values = interaction.values || {}; | ||
| await ctx.kv.set("settings:gtmContainerId", values.gtm_container_id || ""); | ||
| await ctx.kv.set("settings:gtmDataLayerName", values.gtm_data_layer_name || "dataLayer"); | ||
| await ctx.kv.set( | ||
| "settings:gtmScriptUrl", | ||
| values.gtm_script_url || "https://www.googletagmanager.com/gtm.js", | ||
| ); | ||
| await ctx.kv.set( | ||
| "settings:gtmNoScriptUrl", | ||
| values.gtm_noscript_url || "https://www.googletagmanager.com/ns.html", | ||
| ); | ||
|
Comment on lines
+54
to
+65
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [needs fixing] The admin form submission handler stores arbitrary strings from |
||
|
|
||
| const response = await buildSettingsBlocks(ctx); | ||
| return { | ||
| ...response, | ||
| toast: { message: "GTM settings saved", type: "success" }, | ||
| }; | ||
| } | ||
|
|
||
| return { blocks: [] }; | ||
| }, | ||
| }, | ||
| }, | ||
| }); | ||
|
|
||
| async function buildSettingsBlocks(ctx: PluginContext) { | ||
| const containerId = (await ctx.kv.get<string>("settings:gtmContainerId")) || ""; | ||
| const dataLayerName = (await ctx.kv.get<string>("settings:gtmDataLayerName")) || "dataLayer"; | ||
| const gtmScriptUrl = | ||
| (await ctx.kv.get<string>("settings:gtmScriptUrl")) || | ||
| "https://www.googletagmanager.com/gtm.js"; | ||
| const gtmNoScriptUrl = | ||
| (await ctx.kv.get<string>("settings:gtmNoScriptUrl")) || | ||
| "https://www.googletagmanager.com/ns.html"; | ||
|
|
||
| return { | ||
| blocks: [ | ||
| { type: "header", text: "Google Tag Manager" }, | ||
| { | ||
| type: "section", | ||
| text: "Configure your Google Tag Manager container and advanced URLs.", | ||
| }, | ||
| { type: "divider" }, | ||
| { | ||
| type: "form", | ||
| block_id: "gtm_settings_form", | ||
| fields: [ | ||
| { | ||
| type: "text_input", | ||
| action_id: "gtm_container_id", | ||
| label: "Container ID", | ||
| initial_value: containerId, | ||
| placeholder: "GTM-XXXXXXX", | ||
| }, | ||
| { | ||
| type: "text_input", | ||
| action_id: "gtm_data_layer_name", | ||
| label: "Data Layer Name", | ||
| initial_value: dataLayerName, | ||
| placeholder: "dataLayer", | ||
| }, | ||
| { | ||
| type: "text_input", | ||
| action_id: "gtm_script_url", | ||
| label: "GTM Script URL (gtm.js)", | ||
| initial_value: gtmScriptUrl, | ||
| placeholder: "https://www.googletagmanager.com/gtm.js", | ||
| }, | ||
| { | ||
| type: "text_input", | ||
| action_id: "gtm_noscript_url", | ||
| label: "GTM NoScript URL (ns.html)", | ||
| initial_value: gtmNoScriptUrl, | ||
| placeholder: "https://www.googletagmanager.com/ns.html", | ||
| }, | ||
| ], | ||
| submit: { label: "Save Settings", action_id: "save_gtm" }, | ||
| }, | ||
| ], | ||
| }; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| { | ||
| "extends": "../tsconfig.base.json", | ||
| "compilerOptions": { | ||
| "outDir": "./dist", | ||
| "rootDir": "./src", | ||
| "jsx": "react-jsx" | ||
| }, | ||
| "include": ["src/**/*"], | ||
| "exclude": ["node_modules", "dist"] | ||
| } |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
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.
[suggestion] The
authorfield contains the placeholder value"Your Name". Update it to the actual author or remove the field.