Javascript Inside Views

Currently if I need to add some JS inside the view, I have to use


$this->registerJs('some JS code here');

which looks dirty to me:

  • no syntax highlighting in IDE

  • need to watch for single/double quotes (and escape if needed)

Isn’t it better to use widget-like style, for example


<?php RegisterJS::begin(); ?>

<script>

    var myvar = 1;

    function test() {...}

    ...

</script>

<?php RegisterJS::end(); ?>

I use the heredoc notation:




<?php

$script = <<<JavaScript

    var myvar = 1;

    function test() {...}

    ...

JavaScript;

Yii::app()->getClientScript()->registerScript('id',$script);



This way I DO get syntax highlight in vim. Netbeans doesn’t support that though. But you DO get good variable substitution, same as in double quotes but no need to escape double quotes.

It’s not very convenient since it’s hard to make php parse static class methods in heredocs.

For example:


<?php

$script = <<<JavaScript

var t = '{Html::url(...)}'; /// kill me plz

JavaScript;

?>

And still no syntax highlight (in most IDEs).

Btw I just realized that it’s only a few lines of code.

In case someone was wondering here’s my widget:




<?php


namespace app\components;

use yii\base\Widget;


class JS extends Widget

{

	/**

	 * Starts recording code block.

	 */

	public function init()

	{

		ob_start();

		ob_implicit_flush(false);

	}


	/**

	 * Ends recording code block.

	 * This method stops output buffering and registers result as inline javascript.

	 */

	public function run()

	{

		$code = ob_get_clean();

		$code = preg_replace('/<\/?script[^>]*>/', '', $code);

		$this->view->registerJs($code);

	}

}

An this goes into view file:


<? JS::begin() ?>

<script>

function test() {

    console.log('it works');

}

</script>

<? JS::end() ?>

PS “script” tags are left for correct syntax highlight in my editor. They’re explicitly removed by the widget.

Cheers.

To be honest can’t see why you’d add js in the view any more anyway. Its much more convenient to have js in a single files to contend with duplicated code and the overhead is sorted by minifying it and compressing it.

Most application level js is moving towards this methodology anyways if you consider backbone with its views and routes and requirejs for on demand loading.




<?$this->beginClip('js');?>

<script>

    var myvar = 1;

    function test() {...}

    ...

</script>

<?$this->endClip();?>

<?Yii::app()->getClientScript()->registerScript('js',$this->clips['js']);?>



Depends on task.