Smarty version 2 is confused by the curly braces used by Javascript code; it tries to interpret them as open tags. To avoid this issue, the content of the <script> element is usually enclosed in a {literal} Smarty block.
The drawback is that you have to close the {literal} block and open it again if you need to use Smarty functions to generate a fragment of the Javascript block.
In Smarty 2, it works like this:
{assign var="text" value="Hello world!"}
<script>
{literal}
if (myjsVar == '2') {
alert('{/literal}
{* Smarty code here *}
{$text|escape:'javascript'}
{*
* End of the Smarty code; start another 'literal' block
* for the rest of the Javascript code
*}
{literal}');
}
{/literal}
</script>
The generated text looks like this:
<script>
if (myjsVar == '2') {
alert('Hello world!');
}
</script>
Smarty 3 doesn't need enclosing the script in a {literal} block as long as the curly braces ({ and }) are surrounded by whitespace characters.
Update:
Alternatively, if the block of Javascript contains just a few braces and a lot of Smarty code you can forget about the {literal} blocks and use {ldelim} and {rdelim} for { and }.
Like this:
{assign var="text" value="Hello world!"}
<script>
if (myjsVar == '2') {ldelim}
alert('{$text|escape:'javascript'}');
{include file="inc.html"}
{rdelim}
</script>
It works the same in both Smarty versions 2 and 3.