ExpressionEngine / ExpressionEngine

ExpressionEngine is a flexible, feature-rich, free open-source content management platform that empowers hundreds of thousands of individuals and organizations around the world to easily manage their web site.

Home Page:https://expressionengine.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

ee()->TMPL->parse_variables() doesn't behave as expected with an empty array

swierczek opened this issue · comments

Description of the problem
When using ee()->TMPL->parse_variables() with an empty set, variables don't get parsed as expected - at least not quite as described at https://docs.expressionengine.com/latest/development/legacy/libraries/template.html#automatic-variables.

  1. I would expect it to not render anything inside of the tag pair, as there is no data to iterate over
  2. Or at least I would expect it to automatically set {total_results} to 0

How To Reproduce
Create a custom template tag in a custom add-on such as:

public function test_tag()
{
    $channelId = ee()->TMPL->fetch_param('channel_id');

    $data = ee('db')
        ->select('title as test_entry_title, entry_id as test_entry_id')
        ->from('channel_titles')
        ->where('channel_id', $channelId)
        ->limit(5)
        ->get()
        ->result_array();

    return ee()->TMPL->parse_variables(
        ee()->TMPL->tagdata,
        $data
    );
}

Then create/edit a template to use this with a valid channel_id:

{exp:testing:test_tag channel_id="1"}
    total results: {total_results}<br>
    count: {count}<br>
    {test_entry_title} ({test_entry_id})<br>
{/exp:testing:test_tag}

As expected, this will output up to 5 entry titles and their IDs from the given channel ID, along with the total_results and count.

Then change the template tag to an invalid channel ID, such as {exp:testing:test_tag channel_id="-1"}

Now, the template outputs the following (verbatim):

total results: {total_results}
count: {count}
{test_entry_title} ({test_entry_id})

I'd expect this to output nothing because the tag pair loop shouldn't get iterated over at all.


Additionally, it seems like total_results inside of a conditional does somehow work as expected.

{exp:testing:test_tag channel_id="-1"}
    {!-- testing != 0 logic --}
    {if total_results != 0}
        total not 0<br>
    {if:else}
        total is 0<br>
    {/if}

    {!-- testing == 0 logic --}
    {if total_results == 0}
        total is 0<br>
    {if:else}
        total not 0<br>
    {/if}
{/exp:testing:test_tag}

outputs "total is 0" twice with an invalid channel ID, while a valid channel ID outputs "total not 0" twice.

But {total_results} outside of a conditional doesn't get parsed with an empty data set, so something like this doesn't work as expected:

{if '{exp:testing:test_tag channel_id="-1"}{total_results}{/exp:testing:test_tag}' == '0'}
    0 results<br>
{if:else}
    more than 0 results<br>
{/if}

This outputs "more than 0 results" with an invalid channel ID, because the conditional gets parsed as {if '{total_results}' == '0} which is false.

Environment Details:

  • Version: 7.3.12
  • PHP Version 8.0.33