How to Render Arbitrary Script Attributes Using laminas-view's HeadScript Helper

How to Render Arbitrary Script Attributes Using laminas-view's HeadScript Helper

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, 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).

fathom
Figure 1. fathom home page

However, when including fathom's JavaScript file, you also need to include an arbitrary attribute, which you can see in the example below.

1
2
3
4
<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.
— https://usefathom.com/
💡
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.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<?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.

1
2
3
4
->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:

1
2
3
4
5
6
7
->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.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<?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.

Want to Learn More About Mezzio?

Mezzio Essentials teaches you the fundamentals of PHP's Mezzio framework — the fundamentals that you need — to begin building get paid for applications with the Mezzio framework right away. It’s a practical, hands-on approach, which shows you just enough of about the underlying principles and concepts before stepping you through the process of creating an application.

You might also be interested in these tutorials too...

How to Use a CSRF Token in a Mezzio Application
Tue, Mar 2, 2021

How to Use a CSRF Token in a Mezzio Application

No matter how small your web app may be, security is essential! In this tutorial, you’ll learn how to add a CSRF token in forms used in Mezzio-based applications, to prevent attackers from being able to force your users to execute malicious actions.

How to Manually Create a Mezzio Application
Thu, Aug 13, 2020

How to Manually Create a Mezzio Application

If you want to build applications in PHP — from one-page apps to enterprise-grade applications — PHP’s Mezzio framework is a excellent framework to choose. In this tutorial, which is an excerpt from my new book, Mezzio Essentials, I’ll show you how to manually build an application in Mezzio.

Goodbye Master Zend Framework. So Long. Farewell.
Wed, Jul 8, 2020

Goodbye Master Zend Framework. So Long. Farewell.

It’s with some sadness, that earlier this week, I wished a fond farewell to the biggest blog I ever created, Master Zend Framework. Given that, it only feels right — and responsible — to talk about what motivated the decision to close the blog, and what the future holds for the blog’s content.


Want more tutorials like this?

If so, enter your email address in the field below and click subscribe.

You can unsubscribe at any time by clicking the link in the footer of the emails you'll receive. Here's my privacy policy, if you'd like to know more. I use Mailchimp to send emails. You can learn more about their privacy practices here.

Join the discussion

comments powered by Disqus