What is the recommended way to add section specific javascript to entry pages? I need to make some 3rd party api calls front end for currency conversion but I want to only use it on a specific section entry.
1 Answer
A safe way to add JavaScript resources via the frontend, is to use the {% includeJsFile %}
Twig function in your template. The nice thing about the includeJsFile
function is that it doesn't matter where in your template you call it; the file(s) added will always be output just above your </body>
tag (or wherever else you put your {% getFootHtml() %}
call). Also, the function makes sure that no duplicate resources are requested, even if you have multiple calls to includeJsFile
using the same URL (or filepath, for local resources).
You're not being specific about why the JavaScript should only be loaded for a specific entry, so it's difficult to advise about the optimal way to achieve this – but there's a few different approaches that could work nicely:
For one, you could add a conditional to your template, where you hard code the ID to the entry in question:
{% if entry.id == 100 %}
{% includeJsFile('https://code.jquery.com/jquery-3.0.0.js') %}
{% endif %}
Of course, you can have the conditional look at other attributes, as well:
{% if entry.section.handle == 'awesomeSection' %}
{% includeJsFile('https://code.jquery.com/jquery-3.0.0.js') %}
{% endif %}
If the JavaScript should e.g. be loaded whenever a certain Matrix block type is output, you could do something like this:
{% for block in entry.matrixField %}
{% switch block.type %}
{% case 'someBlockType' %}
...
{% includeJsFile('https://code.jquery.com/jquery-3.0.0.js') %}
{% endswitch %}
{% endfor %}
Remember, includeJsFile
handles duplicate requests for you, so it doesn't matter if there's more than one someBlockType
block – the actual external JS resource will only be requested once.
Of course, the most flexible option – and the one I would recommend – would be to add a custom field to your entry type, where you can add URL(s) to external scripts that should be loaded. This makes it easy to add external JavaScript resources to any entry, via the regular editing form in the CP. For this, the Table fieldtype will do nicely (the following assumes a table field with the handle externalScripts
and a single column called url
):
{% for row in entry.externalScripts %}
{% if row.url %}
{% includeJsFile(row.url) %}
{% endif %}
{% endfor %}
Finally, another approach would be to add a PlainText field to your entry type (multiple lines, i.e. a textarea), where you can paste in a full <script>
tag, e.g.:
<script src="https://code.jquery.com/jquery-3.0.0.js" integrity="sha256-jrPLZ+8vDxt2FnE1zvZXCkCcebI/C8Dt5xyaQBjxQIo=" crossorigin="anonymous"></script>
If go down this path, you can't use includeJsFile
and will have to output the string "manually" – making sure to add the |raw
filter to prevent Twig from escaping the HTML (the following assumes your plaintext field is called scripts
):
{{ entry.scripts|raw }}
For the latter option, you might want to add a {% block scriptsInFooter %}
to your base layout, in order to have the value for the scripts
field render in the appropriate place:
{# Entry template #}
{% block scriptsInFooter %}
{{ entry.scripts|raw }}
{% endblock %}
{# Base template #}
...
{% block scriptsInFooter %}{% endblock %}
</body>
-
+1 thanks for the in depth response - way beyond what i was hoping. includeJS looks like it will do the trick - it is for a snipcart integration and I want to ajax to 3rd party currency conversion on entry products– joomkitCommented Jun 27, 2016 at 11:27