Javascript for Pages

The Javascript methods within the {{ _page }} object allow you to output Javascript in your template or set Javascript files and inline Javascript to be included on certain pages. Often the core Javascript for a site is set within the site template or snippet, but there are times when certain Javascript is needed for specific pages.

Some example scenarios include:

  • Javascript is needed to validate a contact form
  • You need to include Javascript to open gallery photos in a lightbox
  • Javascript needs to be included to run a slideshow for a collection widget

You can include Javascript files or inline Javascript in any type of template. You can output the Javascript in any template as well, although it's traditionally set in a site template or site snippet.

The methods discussed on this page allow you to use code to centralize your Javascript files and inline Javascript. They are more powerful than using <script> tags.
However, you can simply use <script> tags in your templates. You do not need to use these methods if you don't want to.

Javascript groups

Including Javascript files

Including inline Javascript

Register files as being used

Outputting Javascript

Accessing Javascript files and inline Javascript

Test to see if a file has been set

Javascript Groups

When you set and output Javascript files and/or inline Javascript you can organize your Javascript in groups. A simple scenario would be to have some Javascript that you want to include at the end of the HTML and some Javascript to include in the <head> section of the HTML.

The default group is 'default'. If no group is passed when adding or outputting Javascript then the 'default' group will be used.

Below is an example of setting a Javascript file to be included in the 'footer' group.

{% do _page.addJs('/path/to/file.js', {'group': 'footer'}) %}

You can then output it in your template with

{{ _page.js('footer') }}

You can call the groups whatever you want as long as it's an alphanumeric string. 'footer' is just an example used here.

Including Javascript files

You use the {% do _page.addJs() %} method to include page-specific Javascript files in your templates.

You do not need to do this for any core Javascript files needed for your website. You can simply put the <script> tags in your template like normal.

Examples

Include a Javascript file to the default group.

{% do _page.addJs('/path/to/file.js') %}

This will output the following for {{ _page.js() }}

<script src="/path/to/file.js"></script>

Include a Javascript file to a group named bottom.

{% do _page.addJs('/path/to/file.js', 'bottom') %}

The following is equivalent:

{% do _page.addJs('/path/to/file.js', {'group': 'bottom'}) %}

Those will output the following for {{ _page.js('bottom) }}

<script src="/path/to/file.js"></script>

Setting script tag attributes

You can also set attributes for the <script> tag when adding a Javacript file. Any valid attribute can be set.

{% do _page.addJs('/path/to/file.js', {'async': true, 'class': 'myClass'} %}

This will output the following for {{ _page.js() }}

<script src="/path/to/file.js" async class="myClass"></script>

{% do _page.addJs('/path/to/file.js', {'async': true, 'defer': true, 'group': 'head'} %}

This will output the following for {{ _page.js('head') }}

<script src="/path/to/file.js" async defer></script>

If the 'async' or 'defer' attributes are set with any value then they will be added as attributes to the script tag with no value.

<script src="/file.js" async defer></script>

Prepending files

If you need a specific Javascript file to be first then you can do the following.

{% do _page.prependJs('/path/to/file.js') %}

You can assign the Javascript file to a group and/or set any <script> tag attributes just like the _page.addJs() method.

{% do _page.prependJs('/path/to/file.js', {'async': true, 'defer': true, 'group': 'head'} %}

Including Inline Javascript

In addition to setting page-specific Javascript files you can also set page-specific inline Javascript.

There are two ways to add inline Javascript to a page. For one-line snippets, you can use the {% do _page.addInlineJs() %} method. For longer code you would use the {% inlinejs %} {% endinlinejs %} tags to capture any inline Javascript to include on the page.

If you add the exact same inline Javascript multiple times it will only be outputted once within a group. This is useful if you have a component like an image slider that is used multiple times on a page. By only outputting the unique inline Javascript once you don't have to worry about a component getting initialized multiple times.

Including short Javascript

Below are some examples of including a short snippet of Javascript. Just like including a Javascript file you can specify the group to include the Javascript in as well as specify any <script> tag attributes.

Simple example.

{% do _page.addInlineJs('alert("test");') %}

That will output the following for {{ _page.js() }}

<script>
alert("test");
</script>

Included some inline Javascript and assign it to the footer group.

{% do _page.addInlineJs('alert("test");', 'footer') %}

The following is equivalent.

{% do _page.addInlineJs('alert("test");', {'group': 'footer'}) %}

Those will output the following for {{ _page.js('footer') }}

<script>
alert("test");
</script>

Include some inline Javascript and add some attributes to the <script> tag and assign to the head group.

{% do _page.addInlineJs('alert("test");', {'class': 'js-class', 'group': 'head'} %}

That will output the following for {{ _page.js('head') }}

<script class="js-class">
alert("test");
</script>

Include larger blocks of inline Javascript

You would use the {% inlinejs %} {% endinlinejs %} tags to capture any inline Javascript to include on the page.

Below is a simple example.

{% inlinejs %}
    console.log('inline js works');
{% endinlinejs %}

That will output the following for {{ _page.js() }}

<script>
    console.log('inline js works');
</script>

You can specify a group to assign the Javascript to.

{% inlinejs group="footer" %}
console.log(' footer inline js works');
{% endinlinejs %}

That will output the following for {{ _page.js('footer') }}

<script>
    console.log('inline js works');
</script>

Any other tag attributes other than 'group' are included as attributes for the <script> tag.

{% inlinejs group="footer" id="footer-inline-js" %}
console.log('footer inline js works');
{% endinlinejs %}

That will output the following for {{ _page.js('footer') }}

<script id="footer-inline-js">
    console.log('footer inline js works');
</script>

Prepending Inline Javascript

If you need a certain block of inline Javascript to appear first in it's group then you can prepend the Javascript.

{% do _page.prependInlineJs('alert("test");') %}

You can assign the Javascript file to a group and/or set any <script> tag attributes just like the _page.addInlineJs() method.

{% do _page.prependInlineJs('alert("test");', {'class': 'js-class', 'group': 'head'} %}

You can also prepend larger chunks of Javascript code with the {% inlinejs %} {% endinlinejs %} tags by adding prepend="yes" as an attribute on the {% inlinejs %} tag.

{% inlinejs prepend="yes" group="footer" id="footer-inline-js" %}
console.log('footer inline js works');
{% endinlinejs %}

Register files as being used

You can register a Javascript file as being used even if it's not outputted with the {{ _page.js() }} method.

{% do _page.registerJs('/path/to/file.js') %}

A few possible reasons for doing this include:

  1. You might be hard coding the <script> tag for the file in your template and you don't want another template to include that file.
  2. You may be using a library like loadjs to asynchronously load your Javascript files.

For the latter reason, the register method is useful because it allows you to test if a file is being used even if it's not included in the output of Javascript files. Below is an example showing testing for a file. If it's not part of the list of Javascript files used on the page then some inline Javascript is added to load the file and then the file is registered.

{% if _page.hasJs('js/forms.js'|theme_url) == false %}
    {% inlinejs %}
        loadjs('{{ 'js/forms.js'|theme_url }}', 'form');
    {% endinlinejs %}
    {% do _page.registerJs('js/forms.js'|theme_url) %}
{% endif %}

The value that you pass to _page.hasJs() and _page.registerJs() can be whatever you want. It doesn't have to be the file path. The example above is using the file path because it's a unique value. But you can use whatever string you want.

{% if _page.hasJs('myJsFile') == false %}
    {% inlinejs %}
        loadjs('{{ 'js/forms.js'|theme_url }}', 'form');
    {% endinlinejs %}
  {% do _page.registerJs('myJsFile') %}
{% endif %}

Outputting Javascript

The {{ _page.js() }} method is used to output Javascript. It will output any Javascript files and/or inline Javascript that is assigned to the group.

Output any files and/or inline Javascript assigned to the default group.

{{ _page.js() }}

Output any files and/or inline Javascript assigned to the footer group.

{{ _page.js('footer') }}

If no Javascript files or inline Javascript have been assigned to the group, then nothing will be outputted.

You can add Javascript files or inline Javascript after the {{ _page.js() }} tags are set in your templates. The {{ _page.js() }} tags are processed after the entire template and any included code is processed.

Output only files

If you wanted to only output Javascript files then you would do the following:

{{ _page.jsFiles() }}

Output any files assigned to the footer group.

{{ _page.jsFiles('footer') }}

Output only inline Javascript

If you wanted to only output inline Javascript code then you would do the following:

{{ _page.inlineJs() }}

Output any inline Javascript code assigned to the footer group.

{{ _page.inlineJs('footer') }}

Set attributes

You can set attributes to be added to all <script> tags when outputting the Javascript by passing a hash of attributes as the second parameter.

{{ _page.js('group-name', {'async': true}) }}

{{ _page.jsFiles('group-name', {'async': true}) }}

{{ _page.inlineJs('group-name', {'class': 'myClass'}) }}

Accessing Javascript files and inline Javascript

You can access any Javascript files or inline Javascript. For example, you can loop through files and update their attributes.

NOTE: You will only be accessing any files or inline code that has been added at that point in the template rendering process.

Access Javascript files

{% set files = _page.js.files %}

Loop through files and set tag attributes

{% set files = _page.js.files %}
{% for file in files %}
    {% set file.async = true %}
{% endfor %}

{% for file in _page.js.files %}
    {% set file.class = 'myClass' %}
{% endfor %}

Access inline Javascript

{% set inline = _page.js.inline %}

Loop through inline Javascript and set <script> tag attributes

{% set inline = _page.js.inline %}
{% for code in inline %}
    {% set code.class = 'myClass' %}
{% endfor %}

{% for code in _page.js.inline %}
    {% set code.class = 'myClass' %}
{% endfor %}

Test to see if a file has been set

You can test and see if a Javascript file has been set yet and use that to determine if you want to add some other code.

NOTE: You don't need to do this to ensure that there are no duplicate references to any Javascript files. The system automatically handles duplicates to only include any Javascript files once within a group.

This could be useful for setting inline Javascript to load files asynchronously for performance reasons. When you are doing that you typically use some sort of library like loadjs to load the Javascript file and let you know when it's loaded so that you can execute your code that depends on that file.

// define a dependency bundle
loadjs(['/path/to/foo.js', '/path/to/bar.js'], 'foobar');

// execute code when the bundle loads
loadjs.ready('foobar', {
    success: function() { /* foo.js & bar.js loaded */ },
    error: function(depsNotFound) { /* foobar bundle load failed */ }
});

If there was a chance that you could load the same file twice you would want to avoid that to prevent any Javascript errors.

{# Test for the file first before setting it to be loaded #}
{% if _page.hasJs('/path/to/file.js') == false %}
    {% inlinejs %}
        loadjs(['/path/to/file.js'], 'myfile');
    {% endinlinejs %}
{% endif %}

{# work with the file once it's loaded #}
{% inlinejs %}
loadjs.ready('myfile', {
    success: function() {
       // Your code here
    }
});
{% endinlinejs %}

The path to the file must be the full path to the file from the site root and should start with / , http:// or https://.

You can use the theme_url or file_url filters when testing or registering files.

{# Test for the file first before setting it to be loaded #}
{% if _page.hasJs('/path/to/file.js'|theme_url) == false %}
    {% inlinejs %}
        loadjs(['/path/to/file.js'], 'myfile');
    {% endinlinejs %}
    {% do _page.registerJs('/path/to/file.js'|theme_url) %}
{% endif %}
{# Test for the file first before setting it to be loaded #}
{% if _page.hasJs('/path/to/file.js'|file_url) == false %}
    {% inlinejs %}
        loadjs(['/path/to/file.js'], 'myfile');
    {% endinlinejs %}
    {% do _page.registerJs('/path/to/file.js'|file_url) %}
{% endif %}