0

I need to add google tag manager (Gtag) to all pages (modules) of the project. Gtag-code consists of 3 files:

- 2 files with js-code, that needs to be included in <head> tag,
- 1 file with <noscript> tags that need to be included in <body> tag.

Each module of my project contains layout.php and AppAsset.php. js-files in these layouts need to be included in <body> tag.

So, I created GlobalAppAsset.php, define $js-property there:

class GlobalAppAsset extends AssetBundle
{
    public $basePath = '@webroot';
    public $baseUrl = '@web';

    public $js = [
        'js/gtag_script1.js',
        'js/gtag_script2.js',
    ];

    public $jsOptions = ['position' => \yii\web\View::POS_HEAD];
}

AppAsset.php for each module in project I inherit from GlobalAppAsset.php and now I need to merge its $js with $js-property in GlobalAppAsset.php. How can I do it properly?

Also, I need that AppAsset.php's js-files be included in <body>-section of the layout, and GlobalAppAsset.php's $js-files be included in <head>-section. How can I this?

And finally, I need to include Gtag's php-file with <nonscript>-part of gtag in <body>. Is it possible to do it with Assets?

2 Answers 2

2

In your case it will be better to use $depends property in your AppAsset instead of extending the GlobalAppAsset.

You can leave GlobalAppAsset as is and the AppAsset should look like this:

class AppAsset extends AssetBundle
{
    //... other app assets configuration

    public $jsOptions = ['position' => \yii\web\View::POS_BEGIN];
    public $depends = [
        //... some other dependencies
        \fully\qualified\GlobalAppAsset::class
    ];
}

As for including the noscript snippet the assets are not a best way how to do that. There might be some way, for example overriding the register() method to register yii\web\View::EVENT_BEGIN_BODY then outputing the snippet in the registered event handler.

class GlobalAppAsset extends AssetBundle
{
    public $basePath = '@webroot';
    public $baseUrl = '@web';

    public $js = [
        'js/gtag_script1.js',
        'js/gtag_script2.js',
    ];

    public $jsOptions = ['position' => \yii\web\View::POS_HEAD];

    public static function register($view) {
        parent::register($view);
        $view->on(
            \yii\web\View::EVENT_BEGIN_BODY,
            function($event) use ($view) {
                echo $view->render('the-view-with-noscript');
            }
        )
    }
}

This solution might work but because this solution is not exactly standard it might cause issues with maintaining the code later.

The better solution for that would be using a widget but you will need to run the widget in each of your layout files.

Sign up to request clarification or add additional context in comments.

3 Comments

Wow great, use $depends property!
that is a nice answer i never thought of that +1
Now that i think about it, i'm not sure if the register() method is called when the asset bundle is registered only as dependency. If it's not called you might need to move the event registration to init() method and access view object as Yii::$app->view.
1

You can use the $cssOptions to include the file inside the <noscript> tag like below

public $cssOptions = ['noscript' => true];

see HERE for details

EDIT

As its not a css file that you want to wrap inside the <noscript> tag, and you have multiple modules and you dont want to write it inside eacho of the layout files, a better approach would be to create a separate view file with your code

google-tag.php

 <!-- Google Tag Manager (noscript) --> <noscript> <iframe src="googletagmanager.com/ns.html?id=GTM-XXXXXX" height="0" width="0" style="display:none;visibility:hidden"></iframe> </noscript> <!-- End Google Tag Manager (noscript) --> 

and include it using

$this->render('google-tag')

8 Comments

Thank you for the quick reply! My php-file that I need to register in EVERY layout: <!-- Google Tag Manager (noscript) --> <noscript> <iframe src="googletagmanager.com/ns.html?id=GTM-XXXXXX" height="0" width="0" style="display:none;visibility:hidden"></iframe> </noscript> <!-- End Google Tag Manager (noscript) --> How can I register it via assets?
i wont recommend using the Assets file for including the iframe that you have specified you can include it manually inside the head tag within the layout file @Dmitry , apart from it is there any special reason you want it to be included via Assets class?
The problem is I have multiple modules and I need to include iframe-code to each of it. Yes, I can include code manually, but I'm trying to find universal solution that helps me include code once. Maybe there is another way except Assets?
then you can create a separate view file with the iframe code and include it using $this->render('your_view_name') inside your layouts , would that be a better approach that would work for you ? @Dmitry as i dont find any other option to do that other than these 2
yes, I alreary did it. But a thought there is a way to include iframe once in some place instead of include it manually in every module.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.