How to check a complex condition in Smarty(PHP) - php

I need to display a section or another in a smarty template. My condition is simple: if a smarty value starts with a string I should display one section, otherwise the other smarty section should be displayed. I can change only the tpl files.
{php}
if (substr($url,0,4) != 'http')
{
{/php}
section 1
{php}
}
else
{
{/php}
section 2
{php}
}
{/php}
The problem is that I can not read the url varible which was previously assigned using $smarty->assign. Basically, I'm looking for the smarty function that can be used to retrieve a value, or if there is a better solution.

First, I would clean up your code. You don't need php tags, you're using smarty:
{if substr($url,0,4) neq 'http'}
section 1
{else}
section 2
{/if}
That's untested but it should be pretty close..
Now, if you're trying to read something like a constant, for example a server variable like HTTP_HOST, you can do something like this:
{assign var='url' value=$smarty.server.HTTP_HOST}
{if substr($url,0,4) neq 'http'}
section 1
{else}
section 2
{/if}

Related

How to print the content of an array in phpfox

I'm working on a legacy application that is written in PHPfox.
There is this foreach loop in one of my view.html.php files:
{foreach from=$aReportSubmissions key=iKey item=aReportSubmission}
<td>{$aReportSubmission.event_name}</td>
{/foreach}
The problem is that $aReportSubmission.event_name is an array and it gets outputted as Array. How can I loop through this variable and show the individual events?
PHPfox uses template tags that resemble Smarty template engine.
The following did NOT work for me:
{foreach from=$aReportSubmission.event_name item=iEvent} {iEvent},{/foreach}
I can see $ is missing before iEvent inside the inner loop
Check if this is works
{foreach from=$aReportSubmissions key=iKey item=aReportSubmission}
<td>{foreach from=$aReportSubmission.event_name item=iEvent} {$iEvent},{/foreach}</td>
{/foreach}
Try with this
{foreach from=$aReportSubmissions key=iKey item=aReportSubmission}
{$aReportSubmission.event_name|print_r}
{/foreach}

Smarty if isset

Okay so I have some PHP code but I have recently changed to smarty. And I was wondering how I convert that PHP code to smarty code.
PHP CODE
<?php
if (isset($_SESSION['user']['id']))
{
echo "You are logged in using method 1";
}
if (Users::isuser())
{
echo "You are logged in using method 2
}
?>
My Attempt so far
{if isset($_SESSION['user']['id'])} You are logged in using method 1 {/if}
{if Users::isuser } You are logged in using method 2 {/if}
But they booth fail? Help me please!
You don't need to and you shouldn't convert everything to smarty.
In PHP you should do something like this:
<?php
$smarty->assign('logged_method',0);
$smarty->assign('logged_method_2',0);
if (isset($_SESSION['user']['id']))
{
$smarty->assign('logged_method',1);
}
if (Users::isuser())
{
$smarty->assign('logged_method_2',1);
}
?>
In Smarty you should do something like that:
{if $logged_method eq 1} You are logged in using method 1 {/if}
{if $logged_method_2 eq 1} You are logged in using method 2 {/if}
Smarty should be used only for displaying data and you should not to assign all tasks to smarty (for example, assigning complex variables/objects only to make simple comparisons)
By the way I don't know if you wanted to use in your code else or not so I left all the code unchanged and introduced 2 smarty variables

Can smarty block names be derived from smarty variables

I would like to define smarty block names according to smarty data, but I can't seem to do it.
Example:
{foreach $array as $code}
{block name=block_$code}
<div id='{$code}'></div>
{/block}
{/foreach}
My purpose is to extend a specific block_$code block by a child template. Is this possible or is there some other trick I could use to do this?
Thanks.
You can use the {assign} block and the cat modifier. For example
{foreach $array as $code}
{assign var=foo value="block_"|cat:$code}
{block name=$foo}
<div>
{/block}
{/foreach}
N.b. I've not tested this, but it should work. You might also be able to short-circuit this and just use {block name="block_"|cat:$code}.
I was able to find the following link from 2011 indicating that this wasn't possible at that time. I suspect it still isn't:
http://www.smarty.net/forums/viewtopic.php?t=19805&highlight=block%20variable%20name
The good news it that I was able to figure out how to make my code work without it. I wanted to be able to override just one of the divs defined by the foreach. Here's how I can do it:
Parent:
{foreach $array as $code}
{block name=code_loop}
<div>Normal Stuff</div>
{/block}
{/foreach}
Child:
{block name=code_loop}
{if $code == 'code of interest'}
<div>New Stuff</div>
{else}
{$smarty.block.parent}
{/if}
{/block}

Smarty templates, MVC and variables inside templates

I wanted opinion is it a good practice to do things like this while working with MVC architecture:
{foreach from=$items item="list"}
{if $list.index < 5}
{assign value="good" var=$class_name}
{else}
{if $list.index % 2 eq 1}
{assign value="bad" var=$class_name}
{else}
{assign value="average" var=$class_name}
{/if}
{/if}
{/foreach}
Or should I do such things inside php and then just access with:
{foreach from=$items item="list"}
{$list.class_name}
{/foreach}
The reason I'm asking this is, because I was told it's need to be done inside templates(because it's styling issues and etc), but I think opposite, I think it needs to be done inside PHP controller so that way you leave templates a little bit cleaner.
So what is the better approach and why?
If you referring class_name as in the <a **class="class_name"**>, then yes, You should generate that in the smarty template so that the template has control over how it should look. If you referring class_name to something else that is class Class_name, and you want to print that out. Then no, it should stay within your PHP code.
But all these are neither best practices stated anywhere or documented, but more company standard or team lead preferences. And you do what they want if you want to keep your job smooth and easy.

Smarty html_options

For smarty's html_options function, is there a way to avoid having to do this (other than not using smarty that is)?
{if $smarty.post}
{html_options name=option_1 options=$options selected=$smarty.post.option_1}
{else}
{html_options name=option_1 options=$options}
{/if}
I realize that it won't show up in the template, but it seems like a bad practice to leave something that is not defined in the template (it also fills up my error logs with noise about undefined indexes).
[edit]
What I am looking for is a way to do it like this without having the undefined index errors show up, as well as reducing the smarty noise in the template files.
{html_options name=option_1 options=$options selected=$smarty.post.option_1}
I guess it would more likely be a modified html_options plugin?
[edit]
As per #mmcgrail's idea:
{if isset($smarty.post.option_1)}
{assign var=selected value=$smarty.post.option_1}
{else}
{assign var=selected value=$default.option_1}
{/if}
{html_options name=option_1 options=$options selected=$selected}
I find this even worse because it is creating new variables in the template, straying from the supposed goal of smarty.
I guess this works:
or:
<?php
//[... snip ...]
$option_1 = isset($_POST['option_1'])? $_POST['option_1'] : $default['option_1'];
$template->assign('option_1', $option_1);
$template->display('my_template.tpl');
And in the template:
{html_options name=option_1 options=$options selected=$option_1}
But then what is the point of smarty keeping track of all of the post/get/request/cookie/server/constants if you can't use them in the template without doubling the amount of code you have to write?
try this
{if isset($smarty.post)}
{html_options name=option_1 optins=$options selected=$smarty.post.option_1}
{/if}
i think that answer your question
I know it's like 12y later but ...
While migrating an app to php 8.1 I just hit this same issue :)
So the real solution that worked was
{html_options name=option_1 options=$options selected=$default.option_1|default:""}
Turns out that without writing a separate plugin what I want is not possible... maybe I will do that, something like:
{html_options name=option_1 options=$options selected=$default.option_1 post=option_1}

Categories