If you use laminas-view’s HeadScript helper to conditionally include JavaScript in your PHP applications, make sure you don’t get caught out if you need to included arbitrary script attributes. Here’s how to do it.
Let’s Get Started
Recently, I decided to try out the privacy-focused Fathom Analytics, as an alternative to Google Analytics, on the website for one of my books (Mezzio Essentials).
Given that the integration, at its most basic, only requires including fathom’s JavaScript to be included on the site, I expected that I’d be a finished in about 5 minutes (including commit and redeploy).
However, when including Fathom’s JavaScript file, you also need to include an arbitrary attribute, which you can see in the example below.
<script
src="https://cdn.usefathom.com/script.js"
data-site="ABCDEFG"
defer>
</script>
This is used to identify the account for which the analytics data is being recorded for.
Why?
As they say on their website:
We are the proud inventors of cookieless website analytics and our software is compliant with GDPR, ePrivacy, PECR, CCPA, and COPPA.
TIP: Check out the details of the Script element on MDN for more details.
No, this is not a cheap plug for them, though I am really happy with the experience so far!
So what does this all have to do with the Mezzio Essentials site?
Well, as you might expect from being a landing page for a book about PHP’s Mezzio Framework, it’s built with Mezzio, which uses Laminas components.
Specifically, it uses laminas-view for the, rather simplistic, frontend view layer.
In the relevant view templates, the code uses the HeadScript helper to include the required JavaScript files, such as for using Vue.js, and MailChimp.
I’ve included a small example here below.
<?php
$this->headScript()
->appendFile(
'https://cdn.jsdelivr.net/npm/vue/dist/vue.js',
'text/javascript'
);
echo $this->headScript();
?>
Given that, at first, I thought that all I’d need to do to get Fathom Analytics running was to add another call to appendFile()
and change the first parameter to Fathom’s URI, such as in the example below.
->appendFile(
'https://cdn.usefathom.com/script.js',
'text/javascript',
)
However, that won’t include the custom attribute.
At this point, I had a look at appendFile()
’s definition and noticed that the method supports a third parameter, an array of attributes.
So I changed the call to appendFile()
to the example below:
->appendFile(
'https://cdn.usefathom.com/script.js',
'text/javascript',
[
'data-site' => 'ABCDEFG'
]
)
However, after reloading the page, the custom attribute still wasn’t rendered.
That’s when I noticed this, small, paragraph in the HeadScript docs:
Arbitrary Attributes are Disabled by Default
By default, HeadScript only will render <script> attributes that are blessed by the W3C.
These include id, charset, crossorigin, defer, integrity, language, src, and type.
However, some JavaScript frameworks, notably Dojo, utilize custom attributes in order to modify behavior.
To allow such attributes, you can enable them via the setAllowArbitraryAttributes() method:
Given that, I added a call to ->setAllowArbitraryAttributes(true)
at the end of the call to appendFile()
, and the custom attributes were rendered.
For the sake of completeness, here is a complete example.
<?php
$this->headScript()
->appendFile(
'https://cdn.jsdelivr.net/npm/vue/dist/vue.js',
'text/javascript'
)
->appendFile(
'https://cdn.usefathom.com/script.js',
'text/javascript',
[
'data-site' => 'YAAAAAAA'
]
)
->setAllowArbitraryAttributes(true);
echo $this->headScript();
?>
That’s how to render arbitrary script attributes using Laminas View’s HeadScript Helper
If you’re using laminas-view’s HeadScript to conditionally include JavaScript in your PHP application, whether in a Mezzio application or not, make sure to call setAllowArbitraryAttributes(true)
so that the attributes will be rendered on page load.
Join the discussion
comments powered by Disqus