3

Hoping someone's come across this before. I'm trying to get some javascript added to a phtml file in Magento 2, but instead of interpreting it as javascript it seems to be outputting it as plain text.

Initially I tried to get it working by using the usual javascript tags in the template file

<script type="text/javascript">
        $("#countdown-before")
            .countdown("<?php echo $this->start;?>", function(event){
                $(this).text("<?php echo $this->beforeMessage;?>" + event.strftime('%H:%M:%S'));
            })
</script>

When this output straight to the page I did some research and tried formatting it using reactjs, but had the same problem (not parsing the script tag and instead outputting as text)

<script>// <![CDATA[
        require([
            'jquery'
        ], function ($) {
            console.log('hello world');
        });
    // ]]>
</script>

Is there something I'm missing which is needed with Magento 2 in order to include javascript directly in the template page?

Thanks in advance

edit: Couple of extra details I realised might affect this. The issue is happening on an Enterprise Edition installation and the template file this is stored in is loaded via a widget. Don't know if maybe there's some sanitisation being applied because it's a widget and that's maybe what's breaking it

2
  • The second way should work - Require Js. Try to remove cache and view_preprocessed folder May 11, 2017 at 15:26
  • Thanks, wasn't aware of that particular folder. Still doesn't seem to be working unfortunately though, seems to just output the javascript without the tags now
    – SolidSquid
    May 11, 2017 at 16:09

3 Answers 3

6

I suggest adding javascript through x-magento-init like below. It ensures that your javascript isn't render blocking. x-magento-init is the Magento 2 standard. Do something like

  <script type="text/x-magento-init">
        {
            "*": {
                "<Vendor_Module>/js/hello.js": {}
            }
        }
</script>

now in hello.js you can write whatever you want to. Again this make sure your javascript isn't negatively affecting page speed.

Your javascript then will look something like

define(['jquery'],function($){
    return function(){
        //do something
    }
});

It might look like too much for simple things but it pays to do it this way

4
  • I had seen this, but unfortunately I need to load variables from the block into the javascript, so need to be able to do at least some of the javascript in the template file
    – SolidSquid
    May 12, 2017 at 9:04
  • Oh you can load php variable to script through x-magento-init . Refer to onepage.phtm in checkout module. You just pass the JSON to the script. Also if you wanna do it script way you can try removing type attribute of the script tag.. you will see that too in onepage.phtml May 12, 2017 at 9:12
  • This seems to have been the right solution, although had to do a bit of digging into how requirejs worked with magento to get it implemented. Thanks for the help
    – SolidSquid
    May 25, 2017 at 15:25
  • 1
    No need to add the .js extennsion fo the x-magento-init declaration.
    – Erfan
    Jan 23, 2018 at 5:35
1
require([ 'jquery' ], function ($) { console.log('hello world'); });

If you want to run after page load

<script type="text/javascript">
require(['jquery','domReady!'], function($){
    console.log('hello world');
})
</script>
5
  • So this seems to have the script tags recognised, but the javascript between them is still printed out unfortunately. Running Enterprise Edition if that makes any difference, thought it might be some kind of pre-processor running, maybe because the template is being loaded through a widget?
    – SolidSquid
    May 11, 2017 at 16:07
  • why not you are adding theme.js or script.js May 11, 2017 at 18:46
  • I need to load in variables from the block into the javascript function, so need to be able to at least partially embed the javascript in the template file
    – SolidSquid
    May 12, 2017 at 9:06
  • maybe because the template is being loaded through a widget? => seems like becuase of that, add into header.phtml or footer.phtml file May 12, 2017 at 9:21
  • Unfortunately it's something that needs to be managed as a widget, with variables being set in the widget configuration, so directly embedding it wouldn't really work. Tried embedding the widget directly, but that hasn't resolved the issue
    – SolidSquid
    May 15, 2017 at 13:35
0

Since no one else mentioned it on this question, you can also initialize a component inline by adding it to the element itself using a data attribute:

data-mage-init='{"<component_name>": {...}}'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.