We use cookies to improve your experience. No personal information is gathered and we don't serve ads. Cookies Policy.

ExpressionEngine Logo ExpressionEngine
Features Pricing Support Find A Developer
Partners Upgrades
Blog Add-Ons Learn
Docs Forums University
Log In or Sign Up
Log In Sign Up
ExpressionEngine Logo
Features Pro new Support Find A Developer
Partners Upgrades
Blog Add-Ons Learn
Docs Forums University Blog
  • Home
  • Forums

Trouble with conditionals

Development and Programming

Erin Dalzell's avatar
Erin Dalzell
790 posts
17 years ago
Erin Dalzell's avatar Erin Dalzell

OK, so can I just put it in brackets in the conditional?

UPDATE: YES I CAN!!

So my whole problem had nothing to do with the prep_conditionals, (I don’t think…I will take out the code and see what happens), but with not including {} around the variable in the conditional?

Whew…that clears up a lot of issues and questions I have.

Could that be documented somewhere?

Derek, thanks a ton for your help, it must have been frustrating dealing with someone who didn’t “get it”.

       
Derek Jones's avatar
Derek Jones
7,561 posts
17 years ago
Derek Jones's avatar Derek Jones

No, Erin, though that works, it is not working for the reason you think it is, and is wrong for various reasons. You are no longer parsing the conditional, but are leaving it up to the template parser long after your plugin has been parsed–all your plugin is doing is replacing text, leaving {if 5 > 0} in the template which will be evaluated later. The only reason this works without error is that in this specific case, your variable happens to be a number. The correct solution here is to modify the tagdata after parsing your conditionals, regardless of whether or not a variable exists in the tagdata, and to make sure to always set $this->return_data with however your plugin has modified $TMPL->tagdata.

       
Erin Dalzell's avatar
Erin Dalzell
790 posts
17 years ago
Erin Dalzell's avatar Erin Dalzell
The correct solution here is to modify the tagdata after parsing your conditionals, regardless of whether or not a variable exists in the tagdata, and to make sure to always set $this->return_data with however your plugin has modified $TMPL->tagdata.

OK, you lost me again. Sorry for being so obtuse, but I don’t understand the “modify the tagdata after parsing the conditionals” part. Could you please give me an example of what you mean?

I do want to do this the “correct” way so that I can learn…I hate hacks that just work because I got lucky.

       
Derek Jones's avatar
Derek Jones
7,561 posts
17 years ago
Derek Jones's avatar Derek Jones

It’s as simple as moving one line, Erin. You’re only changing the plugin’s return data when {num_entries} is present in the plugin’s tagdata. I believe you have another similar issue where you have no content appearing at all in certain cases from your plugin. The reason is the same.

Your plugin’s return data is set to an empty string in your class properties. So unless you change it to $TMPL->tagdata, or to a modified version of the tagdata, your plugin returns nothing, and all tagdata is lost. No conditionals are prepped, no variables are parsed, and the entire tagblock in your template is simply replaced with an empty string.

Solution: Before the function ends, set $this->return_data to the variable that you were modifying the tagdata with.

$result = $query->row;
$num_entries = $query->row['total_files'];

$tagdata = $FNS->prep_conditionals($TMPL->tagdata, $result);

foreach ($TMPL->var_single as $key => $val)
{
    switch ($val)
    {
        case "num_entries":
            $tagdata = $TMPL->swap_var_single($val, $num_entries, $tagdata);
        break;
    }
}

$this->return_data = $tagdata;

Note that I pulled $this->return_data = $tagdata; out of your foreach loop and moved it to the end of the function.

Or, just modify $this->return_data instead of using a temporary variable, though I prefer the above for code readability.

global $TMPL;
$this->return_data = $TMPL->tagdata;
$this->return_data = $FNS->prep_conditionals(this->return_data, $result);
...
$this->return_data = $TMPL->swap_var_single($val, $num_entries, $this->return_data);
...
etc.

If you don’t modify $this->return_data, then anything you do in the code is irrelevant.

       
Erin Dalzell's avatar
Erin Dalzell
790 posts
17 years ago
Erin Dalzell's avatar Erin Dalzell

Do I still need to leave the {} around my variable in my template?

If I pull them out:

{if num_entries > 0}

Then I am back to not working again, even with your code suggestions above. Just to make sure I am not doing anything wrong, my complete plugin is:

class Categoree
{
    var $return_data = "";
    
    function Categoree()
    {
        global $DB, $IN, $TMPL, $FNS;
        
        if ( ! preg_match("#(^|\/)C(\d+)#", $IN->QSTR, $match))
        {        
            return '';
        }
                

        $query = $DB->query("SELECT exp_gallery_categories.total_files
                FROM exp_gallery_categories, exp_galleries
                WHERE exp_gallery_categories.gallery_id = exp_galleries.gallery_id AND 
                exp_gallery_categories.cat_id = '".$DB->escape_str($match['2'])."'");

        if ($query->num_rows == 0)
        {
            return '';
        }

        $num_entries = $query->row['total_files'];
        
        $tagdata = $FNS->prep_conditionals($TMPL->tagdata, $query->row);

        foreach ($TMPL->var_single as $key => $val)
        {
            switch ($val)
            {
                case "num_entries":
                    $tagdata = $TMPL->swap_var_single($val, $num_entries, $tagdata);
                    break;
            }
        }

        $this->return_data = $tagdata;
    }
       
Erin Dalzell's avatar
Erin Dalzell
790 posts
17 years ago
Erin Dalzell's avatar Erin Dalzell

And I want to use it, like this:

<div id="sidebar">
        {exp:categoree}
        {if num_entries > 0}
            {exp:gallery:entries gallery="{gallery_name}" orderby="date" sort="desc" columns="10" rows="1"}
                {entries}
                {row_start} {/row_start}
                {row}
                <div class="thumbnail">
                    {if width > height}
                    <div class="landscape">
                        <a href="#" onclick="return getLandscapeImage('placeholder','{image_url}');">{exp:imgsizer:size src="{image_url}" width="{thumb_size}" alt="{title}" }</a>
                    </div>
                    {if:else}
                    <div class="portrait">
                        <a href="#" onclick="return getPortraitImage('placeholder','{image_url}');">{exp:imgsizer:size src="{image_url}" height="{thumb_size}" alt="{title}" }</a>
                    </div>
                    {/if}
                </div> <!-- thumbnail -->
                {/row}
                {row_blank} {/row_blank}
                {row_end} {/row_end}
            {/entries}
            
            {paginate}
                <div class="paginate">
                    {pagination_links}
                </div> <!-- paginate -->
            {/paginate}
            
            {/exp:gallery:entries}
        {/if}
        {/exp:categoree}
        </div> <!-- sidebar -->
       
Derek Jones's avatar
Derek Jones
7,561 posts
17 years ago
Derek Jones's avatar Derek Jones

No, never put brackets around variables in conditionals. You will not find examples of that anywhere in the documentation for a reason. 😉

Here is a KB article that helps define this explicitly, though sticking to what you see in the User Guide is sufficient.

Ok, step back and think about what situation you would have where $num_entries would be <= 0. Wouldn’t it only be when the query had no results? And what are you doing when that happens?

if ($query->num_rows == 0)
{
    return '';
}

You also have another conditionals that can lead to the plugin returning no content whatsoever.

if ( ! preg_match("#(^|\/)C(\d+)#", $IN->QSTR, $match))
{        
    return '';
}

Hopefully that is clear now? If you don’t modify and return tagdata, then you are losing the entire tagblock. The conditional code looks fine, and stripped of everything else, works perfectly. If either of the above two conditionals match, though, your whole tagblock will be wiped.

       
Erin Dalzell's avatar
Erin Dalzell
790 posts
17 years ago
Erin Dalzell's avatar Erin Dalzell

OK, I do understand that, however, in my current situation, I am returning data as I am calling the plugin when I am on a category page (hence the preg_match will succeed) and there is one row returned (verified by printing the row via print_r.

I can verify via echos where I get in the plugin and I do make it all the way to the bottom.

Which means, according to you, it should work, but does not.

So, I must be missing something still. If I place an echo in my case statement it is NOT being printed, so EE is not matching the num_entries in the conditional as tagdata (or something like that)

Again, sorry if I am being obtuse, but I just don’t see how this is supposed to work.

       
Derek Jones's avatar
Derek Jones
7,561 posts
17 years ago
Derek Jones's avatar Derek Jones

Erin, ignore the switch / case. That is within a foreach for template variables. Bracketed variables. That code will not even execute unless you have {num_entries} in your tagdata. Simplify and reduce. In an empty template:

{exp:categoree}
{if num_entries > 0}We have entries!
{/if}
{if num_entries == 1}We have 1 entry!</br >{/if}
{if num_entries > 2}We have more than 1 entry!{/if}
{/exp:categoree}

Then visit that template with URLs corresponding to categories that you know how many entries you have, e.g.

http://example.com/index.php/test/template/C1/ http://example.com/index.php/test/template/C2/ http://example.com/index.php/test/template/C147/

etc.

       
Erin Dalzell's avatar
Erin Dalzell
790 posts
17 years ago
Erin Dalzell's avatar Erin Dalzell
Erin, ignore the switch / case.

By ‘ignore’, do you mean remove from my code?

Or would you like me just to test my existing code in a blank template?

       
Derek Jones's avatar
Derek Jones
7,561 posts
17 years ago
Derek Jones's avatar Derek Jones
Again, sorry if I am being obtuse, but I just don’t see how this is supposed to work.

Trying to break this down separately.

These are variables:

{foo}
{bar}

When they appear in your tagdata, $TMPL->var_single will consist of an array of all such variables. $TMPL->swap_var_single() acts like a specialized version of str_replace(), in that it takes care of the { and } that surround your variables for you, so you just have to supply it with the name of the variable, the data, and the string you are operating on.

These are conditionals:

{if foo > 1}
{if bar == "bat"}

$FNS->prep_conditionals takes an associative array of variable names and their corresponding values. It then preps them for safe use inside a PHP conditional. So given that the above conditionals are in $tagdata, and we have the following associative array:

$cond = array('foo' => 5, 'bar' => 'bat');

Then $FNS->prep_conditionals($tagdata, $cond); will return:

{if "5" > 1}
{if "bat" == "bat"}

You can debug this at any time in your code by dumping $tagdata to the screen and issuing an exit; command, incidentally. In your case:

$tagdata = $FNS->prep_condtionals($TMPL->tagdata, $query->row);
exit($tagdata);
       
Derek Jones's avatar
Derek Jones
7,561 posts
17 years ago
Derek Jones's avatar Derek Jones
Erin, ignore the switch / case.
By ‘ignore’, do you mean remove from my code? Or would you like me just to test my existing code in a blank template?

Ignore as in don’t pay any attention to it right now. If I wanted you to remove it, I would have said remove/delete/comment out/etc. 😛

       
Erin Dalzell's avatar
Erin Dalzell
790 posts
17 years ago
Erin Dalzell's avatar Erin Dalzell

I finally got it to work!!! I missed something that was causing all my confusion. I was getting the total_files from the table and that was in my query row. However, I was storing it as $num_entries in the my plugin. So in my conditional, I used num_entries. However I should have been using ‘total_files’ as that was what was in my result array ($cond in your example).

So I either need to change the name in my plugin, or change the SQL query to store the total_files value in num_entries.

I really, really appreciate the time you took to explain it all to a dummy like me.

I am off to the races now!!

Thanks again!

       
Derek Jones's avatar
Derek Jones
7,561 posts
17 years ago
Derek Jones's avatar Derek Jones

Right on.

       
1 2

Reply

Sign In To Reply

ExpressionEngine Home Features Pro Contact Version Support
Learn Docs University Forums
Resources Support Add-Ons Partners Blog
Privacy Terms Trademark Use License

Packet Tide owns and develops ExpressionEngine. © Packet Tide, All Rights Reserved.