Skip to content

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

@swierczek

Description

@swierczek

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions