0

I'm trying to html encode a string that will be used as a tooltip in a google map.

$cs = Yii::app()->getClientScript();
$cs->registerScript('someID', <<<EOD
    function mapsetup() {
        //...        
        var marker = new google.maps.Marker({
            position: myLatlng,
            map: map,
            // works:
            title: '$model->name'
            // doesn't work:
            title: '{${CHtml::encode($model->name)}}'
            });
       // ...
    }
    mapsetup();
EOD
, CClientScript::POS_LOAD
);

If I use the line title: '$model->name', it results in the following expansion:

title: 'Some Name'

If I instead use the line title: '{${CHtml::encode($model->name)}}', it results in the following expansion:

title: ''

CHtml::encode works elsewhere on the same page fine, but it doesn't seem to work in the php heredoc.

  1. Do I even need to html encode javascript string data that will be rendered to the browser?
  2. How can I get CHtml::encode to work in the heredoc?
User
  • 62,498
  • 72
  • 186
  • 247

2 Answers2

2
  1. You do need to encode the data, but not with CHtml::encode. You have to use CJSON::encode or CJavaScript::encode instead (any one will do) because you are injecting values into JavaScript, not into HTML.
  2. You cannot get it to work. Just calculate the value you need beforehand, store it in a variable an inject the contents of the variable.

So for example:

$title = CJSON::encode($model->name);
$cs = Yii::app()->getClientScript();
$cs->registerScript('someID', <<<EOD
    function mapsetup() {
        //...        
        var marker = new google.maps.Marker({
            position: myLatlng,
            map: map,
            title: $title // no quotes! CJSON::encode added them already
            });
       // ...
    }
    mapsetup();
EOD
, CClientScript::POS_LOAD
);
Jon
  • 428,835
  • 81
  • 738
  • 806
1

It's not the right use-case of interpolation, see this http://www.php.net/manual/en/language.types.string.php#language.types.string.parsing.complex. Just encode model name before and then insert in title:"$encodedName", 1 row is not a big memory use :)

  • Good point about just encoding the name in variable in the previous statement. – User Sep 27 '12 at 23:31
  • I was reading the reference before and it seemed like you could call functions, e.g, `echo "This is the value of the var named by the return value of getName(): {${getName()}}";` I wonder if the problem is in my case my function has an argument and I need to expand the function argument before calling the function. – User Sep 27 '12 at 23:33
  • Yes, it's because of CHtml::method is using input param, that's why interpolation is wrong. So just escape it before, and if needed it will be automatically escaped from js. (not sure just see registerScript for more info). –  Sep 27 '12 at 23:55