ExpressionEngine rendering JS code with { } brackets
Asked Answered
D

4

6

Is there a way to force expression engine to NOT render items within curly brackets as EE code? The google chart tools uses javascript code that contains curly { } brackets, and naturally EE thinks it's a variable and tries to render it. Any way around this?

Delladelle answered 29/6, 2011 at 0:50 Comment(0)
S
19

ExpressionEngine's Template Class parses curly braces {} as template variables, looking for three kinds of variables: single, pair, and conditional variables:

// Single Variable
{summary}

// Pair Variable
{category} ... {/category}

// Conditional Variable
{if segment_2 != ""} ... {/if}

Curly braces in CSS are considered a special condition.

For example, the following CSS is acceptable to place anywhere in a template, and gets intelligently parsed:

<style>
    /* All On One Line = Okay */
    p { margin-bottom: 1em; }

    /* Indented and On Separate Lines = Also Okay */
    p em {
        font-style: italic;
    }

    /* EE Variables are Parsed and Replaced */
    p.{site_name} {
        text-decoration: none;
        }

    /* EE Code is Allowed and Parsed Appropriately */
    {exp:channel:entries channel="channel_name" limit="1"}
        li.{url_title} a {
            color: #c00;
        }
    {/exp:channel:entries}
</style>

Unfortunately, JavaScript is handled differently and prevents the Advanced Conditionals Parser from processing anything in tags. For example, the following JavaScript with curly braces all on one line:

<script>var addthis_config = { 'ui_click': true };</script>

Will be parsed by ExpressionEngine as a template variable and rendered as:

<script>var addthis_config = ;</script>

You'll notice everything starting at the opening { and ending with the closing } curly brace gets parsed and replaced! As a workaround, you can place the braces on separate lines and avoid this problem:

<script>
    var addthis_config = {
        'ui_click': true,
        'data_track_clickback': true
    };
</script>

If you've written a JavaScript function that expects values from ExpressionEngine, just place your braces on separate lines — which is a good coding convention and is optimal for readability:

<script>
    $(document).ready(function() {
        ...
            {exp:channel:entries channel="channel_name" limit="1"}
                var business_name = '{business_website}';
                var business_website = '{business_website}';
            {/exp:channel:entries}
        ...
    });
</script>

As suggested by Ben, you can change this behavior by setting a Hidden Configuration Variable: $conf['protect_javascript'] = 'n';

Sidedress answered 29/6, 2011 at 15:22 Comment(1)
What a great response. This was exactly the information i was looking for regarding some javascript stuff and EE.Freshwater
S
8

What does ExpressionEngine's hidden $config['protect_javascript'] actually do? It's probably best explained by an example — allow me to illustrate.

Given the following code sample, with $config['protect_javascript'] = 'y'; advanced conditionals will completely be ignored:

<script>
    {if username == "admin"}
        Welcome, {username}!
    {if:elseif member_id == "2"}
        Welcome, {screen_name}!
    {if:else}
        Welcome, Guest!
    {/if}
</script>

Which will produce the following output:

<script>
    Welcome, admin!

    Welcome, Administrator!

    Welcome, Guest!
</script>

Whereas, when $config['protect_javascript'] = 'n'; the same code snippet from above will allow advanced conditionals to be evaluated and will produce:

<script>
    Welcome, admin!
</script>

As you can see, the difference is whether or not advanced conditionals are evaluated in JavaScript code blocks.

Simple conditionals and template tags are always evaluated in <script> tags, regardless of the $config['protect_javascript'] setting — just be sure to place your curly braces {} on separate lines!

<script>
    // Simple Conditionals Are Unaffected and Always Work
    {if segment_2 != ""}
        {redirect="404"}
    {/if}
</script>
Sidedress answered 30/9, 2011 at 0:5 Comment(0)
P
0

Create a global variable to contain your JS code. Then just use the global variable in your template:

https://docs.expressionengine.com/v2/templates/globals/index.html

Platelayer answered 10/2, 2017 at 21:41 Comment(0)
E
-1

Simply placing curly braces on separate lines didn't work for me for some reason (I'm using EE v2.1.1). But placing a commented line before and after the braces worked. E.g. for my Google Analytics code:

<script>
(function(i,s,o,g,r,a,m)
//
{
//
i['GoogleAnalyticsObject']=r;i[r]=i[r]||function()
//
{
//
(i[r].q=i[r].q||[]).push(arguments)
//
}
//
,i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
//
}
//
)(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-3636230-46', 'auto');
ga('send', 'pageview');
</script>
Eoin answered 23/9, 2015 at 17:20 Comment(1)
While this may work, not knowing why it worked isn't completely solving the problem. It might be better as a comment at this point until it becomes clear how and why it works.Nyala

© 2022 - 2024 — McMap. All rights reserved.