diff --git a/readme.txt b/readme.txt
index 3bfb48f5..aba8f460 100644
--- a/readme.txt
+++ b/readme.txt
@@ -91,6 +91,7 @@ Yes! Pagespeed is one of our main focus points, and we strive to make the plugin
= 1.X =
Enhancements:
+* Inline scripts are now registered with the wp_add_inline_script insted of wp_head. This allows easy extension GTM Kit and implementation of a CSP (Content Security Policy).
Bugfixes:
* The product ID Prefix was not added when a product variation was selected.
diff --git a/src/Common/Util.php b/src/Common/Util.php
index 20801865..17206845 100644
--- a/src/Common/Util.php
+++ b/src/Common/Util.php
@@ -224,7 +224,8 @@ public function enqueue_script( string $handle, string $script ): void {
$dependency = $deps_file['dependencies'];
$version = $deps_file['version'];
}
+ $dependency[] = 'gtmkit';
- \wp_enqueue_script( $handle, GTMKIT_URL . 'assets/' . $script . '.js', $dependency, $version, true );
+ \wp_enqueue_script( $handle, GTMKIT_URL . 'assets/' . $script . '.js', $dependency, $version, [ 'strategy' => 'defer' ] );
}
}
diff --git a/src/Frontend/Frontend.php b/src/Frontend/Frontend.php
index f5f0f7d8..b73ba472 100644
--- a/src/Frontend/Frontend.php
+++ b/src/Frontend/Frontend.php
@@ -45,108 +45,85 @@ public function __construct( Options $options ) {
*/
public static function register( Options $options ): void {
$page = new Frontend( $options );
+ $container_active = Options::init()->get( 'general', 'container_active' );
+ $noscript_implementation = Options::init()->get( 'general', 'noscript_implementation' );
if ( empty( $options->get( 'general', 'just_the_container' ) ) ) {
- add_action( 'wp_head', [ $page, 'get_header_datalayer' ], 1, 0 );
- add_action( 'wp_head', [ $page, 'get_datalayer_content' ] );
+ add_action( 'wp_enqueue_scripts', [ $page, 'enqueue_settings_and_data_script' ], 1, 0 );
+ add_action( 'wp_enqueue_scripts', [ $page, 'enqueue_datalayer_content' ] );
}
- $container_active = Options::init()->get( 'general', 'container_active' );
-
if ( $container_active ) {
- add_action( 'wp_head', [ $page, 'get_header_script' ], 10, 0 );
+ add_action( 'wp_enqueue_scripts', [ $page, 'enqueue_header_script' ] );
} elseif ( Options::init()->get( 'general', 'console_log' ) ) {
add_action( 'wp_head', [ $page, 'container_disabled' ] );
}
- add_filter( 'wp_resource_hints', [ $page, 'dns_prefetch' ], 10, 2 );
- add_filter( 'rocket_excluded_inline_js_content', [ $page, 'wp_rocket_exclude_javascript' ] );
-
- $noscript_implementation = Options::init()->get( 'general', 'noscript_implementation' );
-
if ( $noscript_implementation === '0' && $container_active ) {
add_action( 'wp_body_open', [ $page, 'get_body_script' ] );
} elseif ( $noscript_implementation === '1' && $container_active ) {
add_action( 'body_footer', [ $page, 'get_body_script' ] );
}
+
+ add_filter( 'wp_resource_hints', [ $page, 'dns_prefetch' ], 10, 2 );
+ add_filter( 'rocket_excluded_inline_js_content', [ $page, 'wp_rocket_exclude_javascript' ] );
+ add_filter( 'wp_inline_script_attributes', [ $page, 'set_inline_script_attributes' ], 10, 2 );
}
/**
- * The dataLayer initialization and settings
+ * The inline script for settings and data use by other GTM Kit scripts.
*/
- public function get_header_datalayer(): void {
+ public function enqueue_settings_and_data_script(): void {
$settings = [
'datalayer_name' => $this->datalayer_name,
'console_log' => Options::init()->get( 'general', 'console_log' ),
];
- ?>
-
-
+ ob_start();
+ ?>
+ window.gtmkit_settings = ;
+ window.gtmkit_data = ;
+ options->get( 'general', 'gcm_default_settings' ) ) : ?>
+ if (typeof gtag === "undefined") {
+ function gtag(){datalayer_name ); ?>.push(arguments);}
+ gtag('consent', 'default', {
+ 'ad_storage': 'options->get( 'general', 'gcm_ad_storage' ) ) ? 'granted' : 'denied'; ?>',
+ 'analytics_storage': 'options->get( 'general', 'gcm_analytics_storage' ) ) ? 'granted' : 'denied'; ?>',
+ 'personalization_storage': 'options->get( 'general', 'gcm_personalization_storage' ) ) ? 'granted' : 'denied'; ?>',
+ 'functionality_storage': 'options->get( 'general', 'gcm_functionality_storage' ) ) ? 'granted' : 'denied'; ?>',
+ 'security_storage': 'options->get( 'general', 'gcm_security_storage' ) ) ? 'granted' : 'denied'; ?>',
+ });
+ } else if ( window.gtmkit_settings.console_log === 'on' ) {
+ console.warn('GTM Kit: gtag is already defined')
+ }
'false',
- 'data-nowprocket' => '',
- 'data-cookieconsent' => 'ignore',
- ]
- );
-
- foreach ( $attributes as $attribute => $value ) {
- echo ' ' . esc_attr( $attribute ) . '="' . esc_attr( $value ) . '"';
- }
+ wp_register_script( 'gtmkit', '', [], GTMKIT_VERSION, [ 'in_footer' => false ] );
+ wp_enqueue_script( 'gtmkit' );
+ wp_add_inline_script( 'gtmkit', $script, 'before' );
}
/**
* The dataLayer content included before the GTM container script
*/
- public function get_datalayer_content(): void {
- ?>
-
- \n";
+ wp_register_script( 'gtmkit-datalayer', '', [], GTMKIT_VERSION, [ 'in_footer' => false ] );
+ wp_enqueue_script( 'gtmkit-datalayer' );
+ wp_add_inline_script( 'gtmkit-datalayer', $script, 'before' );
}
/**
* The Google Tag Manager container script
*/
- public function get_header_script(): void {
+ public function enqueue_header_script(): void {
$gtm_id = Options::init()->get( 'general', 'gtm_id' );
@@ -155,10 +132,8 @@ public function get_header_script(): void {
}
$script_implementation = (int) Options::init()->get( 'general', 'script_implementation' );
- ?>
-
- \n\n";
+ $script = ob_get_clean();
+
+ wp_register_script( 'gtmkit-container', '', [ 'gtmkit-datalayer' ], GTMKIT_VERSION, [ 'in_footer' => false ] );
+ wp_enqueue_script( 'gtmkit-container' );
+ wp_add_inline_script( 'gtmkit-container', $script );
}
/**
@@ -195,11 +174,40 @@ public function get_gtm_script( string $gtm_id ): void {
$domain = Options::init()->get( 'general', 'sgtm_domain' ) ? Options::init()->get( 'general', 'sgtm_domain' ) : 'www.googletagmanager.com';
$loader = Options::init()->get( 'general', 'sgtm_container_identifier' ) ? Options::init()->get( 'general', 'sgtm_container_identifier' ) : 'gtm';
- echo "(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=
- 'https://" . esc_attr( $domain ) . '/' . esc_attr( $loader ) . ".js?id='+i+dl;f.parentNode.insertBefore(j,f);
- })(window,document,'script','" . esc_js( $this->datalayer_name ) . "','" . esc_attr( $gtm_id ) . "');";
+ echo "/* Google Tag Manager */\n";
+ echo "(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':\n";
+ echo "new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],\n";
+ echo "j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=\n";
+ echo "'https://" . esc_attr( $domain ) . '/' . esc_attr( $loader ) . ".js?id='+i+dl;f.parentNode.insertBefore(j,f);\n";
+ echo "})(window,document,'script','" . esc_js( $this->datalayer_name ) . "','" . esc_attr( $gtm_id ) . "');\n";
+ echo "/* End Google Tag Manager */\n";
+ }
+
+ /**
+ * Set inline script attributes
+ *
+ * @param array $attributes The script attributes.
+ * @param string $script The script.
+ *
+ * @return array The script attributes.
+ */
+ public function set_inline_script_attributes( array $attributes, string $script ): array { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed
+ if ( isset( $attributes['id'] ) && strpos( $attributes['id'], 'gtmkit-' ) === 0 ) {
+ $script_attributes = apply_filters(
+ 'gtmkit_header_script_attributes',
+ [
+ 'data-cfasync' => 'false',
+ 'data-nowprocket' => '',
+ 'data-cookieconsent' => 'ignore',
+ ]
+ );
+
+ foreach ( $script_attributes as $attribute_name => $value ) {
+ $attributes[$attribute_name] = $value;
+ }
+ }
+
+ return $attributes;
}
/**
diff --git a/src/Integration/ContactForm7.php b/src/Integration/ContactForm7.php
index 1c16b8d6..e4194cb1 100644
--- a/src/Integration/ContactForm7.php
+++ b/src/Integration/ContactForm7.php
@@ -62,7 +62,7 @@ public function enqueue_scripts(): void {
wp_enqueue_script(
'gtmkit-cf7',
GTMKIT_URL . 'assets/integration/contact-form-7.js',
- [],
+ [ 'gtmkit' ],
$this->util->get_plugin_version(),
true
);
diff --git a/src/Integration/EasyDigitalDownloads.php b/src/Integration/EasyDigitalDownloads.php
index 539b3c32..1221ca5c 100644
--- a/src/Integration/EasyDigitalDownloads.php
+++ b/src/Integration/EasyDigitalDownloads.php
@@ -84,7 +84,7 @@ public function enqueue_scripts(): void {
wp_enqueue_script(
'gtmkit-edd',
GTMKIT_URL . 'assets/integration/edd.js',
- [ 'jquery' ],
+ [ 'gtmkit', 'jquery' ],
$this->util->get_plugin_version(),
true
);
diff --git a/src/Integration/WooCommerce.php b/src/Integration/WooCommerce.php
index 61d9026c..169e9460 100644
--- a/src/Integration/WooCommerce.php
+++ b/src/Integration/WooCommerce.php
@@ -194,7 +194,7 @@ public function enqueue_scripts(): void {
wp_enqueue_script(
'gtmkit-woocommerce',
GTMKIT_URL . 'assets/integration/woocommerce.js',
- [],
+ [ 'gtmkit' ],
$this->util->get_plugin_version(),
true
);