tag-manager icon indicating copy to clipboard operation
tag-manager copied to clipboard

Support variables in Custom JavaScript variable

Open Laul0 opened this issue 4 years ago • 10 comments

Summary

Using an existing variable into a Custom JavaScript variable can avoid a lot of dev and can be really useful. Example: you wish return a custom attribute from current clicked element. Use {{ClickElement}} is essential.

Current behavior

Into a custom javascript variable, add the {{ClickElement}} variable like :

function () { if ({{ClickElement}}) { return {{ClickElement}}.getAttribute('my-attribute'); } else { return ""; } };

This code return the following error:

Screen Shot 2020-01-06 at 16 09 16 Screen Shot 2020-01-06 at 16 09 33

Moreother, when this kind of error occured, the Preview mode break totally 😕

Maybe a similar issue here: https://forum.matomo.org/t/how-to-refer-user-defined-variables-in-custom-javascript/34932

Expected behavior

Add a variable into a custom javascript variable

Laul0 avatar Jan 06 '20 21:01 Laul0

The variable does indeed not support using other variables yet. This is also why it results in a JS error.

What you could try be

function () {
  if (TagManager.dataLayer.get('mtm.clickElement')) {
      return TagManager.dataLayer.get('mtm.clickElement').getAttribute('my-attribute');
  } else { 
      return 'foo';
  }
}

You can find the API for data layer here: https://developer.matomo.org/api-reference/tagmanager/javascript-api-reference#tagmanagerdatalayer

tsteur avatar Jan 07 '20 02:01 tsteur

Hi @tsteur,

Thx you for your useful answer.

May I ask questions about this?

Is it normal that the preview break when a custom script has an error? Maybe check code before enable preview mode (like Google) ou catch the error to keep the Preview panel available?

About the layer, a roadmap is planned to manage this king of syntax? Maybe more easier for people who come from Google to have in then code {{variable}} rather than TagManager. ...?

Laul0 avatar Jan 07 '20 14:01 Laul0

Is it normal that the preview break when a custom script has an error? Maybe check code before enable preview mode (like Google) ou catch the error to keep the Preview panel available?

This variable is kind of a special case where the code you type is basically pasted directly into the container script. Not sure if we can prevent any errors easily. We could probably do it if we continue to not allow any variables and then we would somehow first need to evaluate the entered JS to make sure there is no syntax error before sending it to the backend. If we add the features to allow variables, then it will be bit harder since the frontend / JS logic would basically need to emulate variables and replace these before testing the entered code. Using eval to test syntax is correct is not a solution.

Unless there was some JavaScript syntax checker written in PHP. That would make things easier. To be checked.

refs https://github.com/matomo-org/tag-manager/issues/54

About the layer, a roadmap is planned to manage this king of syntax? Maybe more easier for people who come from Google to have in then code {{variable}} rather than TagManager. ...?

It's currently not planned as we're now focusing on Matomo 4 which mainly includes changes that break APIs etc. After Matomo 4 we will be working on regular fixes and enhancements again.

tsteur avatar Jan 12 '20 19:01 tsteur

@Laul0 I'll reopen the issue for now as we're still planning to support this eventually.

tsteur avatar Jul 12 '20 19:07 tsteur

I'm looking forward to this feature! Any updates on the schedule on this?

aleksijohansson avatar Jun 17 '21 15:06 aleksijohansson

Up, i am also interested to know if this could be integrated as weel. If yes which ETA to expect ? Regards

matmicro avatar Dec 13 '21 20:12 matmicro

Maybe just replace variables with some Matomo variables resolver code

ulcuber avatar Jul 12 '22 10:07 ulcuber

I have tried to extend CustomJsFunctionVariable like:

public function loadTemplate($context, $entity)
{
    if ($js = ($entity['parameters']['javascript'] ?? null)) {
        if (is_array($js)) {
            if (isset($js['joinedVariable']) && is_array($js['joinedVariable'])) {
                $js = array_reduce($js['joinedVariable'], function ($carry, $item) {
                    if (is_string($item)) {
                        return $carry . $item;
                    }
                    if (is_array($item)) {
                        // should be same as $methodName in TemplateLocator@loadVariableTemplate
                        $item['Variable'] = $item['type'] . 'Variable';
                        return $carry . 'TagManager._buildVariable(' . json_encode($item) . ", parameters.get('container'))";
                    }
                    return $carry;
                }, "");
            } else {
                throw new Exception("Expected joined variable");
            }
        }

        $function = rtrim(trim($js), ';');

        return '(function () { return function (parameters, TagManager) { this.get = ' . $function .'; } })();';
    }
}

Currently I am thinking how to extend $entity joinedVariable with needed parameters

ulcuber avatar Jul 20 '22 08:07 ulcuber

This issue has been mentioned on Matomo forums. There might be relevant details there:

https://forum.matomo.org/t/no-preview-mode-syntaxerror-in-console/46782/2

@ulcuber Ill try to check in couple of days if I can help here in someway

AltamashShaikh avatar Jul 28 '22 03:07 AltamashShaikh

Hello, the ticket is a bit older. I know and have understood that it is more complicated than it looks from the user's point of view. But would it be possible to prioritize this topic again? Above it was rejected with the preparatory work for version 4. But now version 5 is imminent. Thanks and best regards.

utrautmann avatar Apr 20 '23 13:04 utrautmann

Another customer requested this functionality today.

9joshua avatar Sep 26 '23 05:09 9joshua