I am using PHP and Smarty. I have a simple application that:
Shows page header
Checks if user is logged in -> check session
Checks if user wants to log out -> then clear session
If logged in shows a menu.
If not logged in, then challenges user for id/password -> set session
Shows page footer
Now I want to add the following to header:
username if logged in
"login" string if not logged in
To do this seems to require the placement of my PrintHeader function to become complicated.
I now cannot print header, until I know if user is logged in/just logged in/has logged out,
plus header has to go before user/password challenge.
What approach can I use here?
Is it possible to buffer a "not logged in" header, then replace it with "logged if header"
if required.
SmartyApp::PrintHeader();
Application->IsLoggedIn()
Application->DoesUserWantsToLogOut()
Application->IfNotLoggedInThenShowChallengeToUser()
Application->IfLoggedInThenShowFullMenu()
SmartyApp::PrintFooter();
I think a more convenient pattern would be to incorporate conditions within the templates themselves, rather than keeping multiple templates for each possible outcome. For example:
$smarty->assign('user', new User($_SESSION));
$smarty->display('index.tpl');
<!-- header.tpl -->
{if $user->isLogged()}
<p>Welcome {$username}</p>
{else}
<p>Please Log In</p>
{/if}
<!-- body.tpl -->
{if $user->isLogged()}
{include file="menu.tpl"}
{else}
<p>You must be signed in to view this menu</p>
{/if}
<!-- index.tpl -->
{include file="header.tpl"}
{include file="body.tpl"}
{include file="footer.tpl"}
The point of Smarty is that it separates logic from design of your page. In your case your logic is now controlling your design and that is not what Smarty is designed to do. If you prefer to control the design from within the application then you shouldn't use Smarty.
If you do want to use Smarty then remove your PrintHeader() and PrintFooter() then inside your Smarty template you put the design related to the display.
Probably the easiest way to do it following your pattern would be for the application to fetch the appropriate template and assign the appropriate variables.
Application->IsLoggedIn(); // assign some login variables
Application->DoesUserWantsToLogOut(); // probably redirect and logout and never get to display
Application->IfNotLoggedInThenShowChallengeToUser(); // template would be the login template
Application->IfLoggedInThenShowFullMenu(); // fetch and assign a menu to the template
$_smarty->display( Application->template );
Then in each smarty template:
{include file=header.tpl }
HTML for each template
{include file=footer.tpl }
Note that you can assign variables to the header and footer includes just like you would the regular template. So if you have a variable {$username} in the header. You just assign it in your Application menu output and it will set. Something like this is probably what you want: {if $username} {$username} {else} Log-In{/if}
Now just as opinion I would design it somewhat differently. I don't think OO means "don't use if statements". I think something like what i have below is clearer:
$app = new App();
if( $app->loggedIn() ) {
if( $app->logout() ) {
$app->redirect('goodbye.php');
}
$smarty->assign( 'menu', $app->menu() );
$smarty->assign( 'user', $app->user() );
$template = 'main.tpl';
}
else {
$template = 'login.tpl';
}
$smarty->display($template);
The smarty templates would look the same as the example I gave above.
Related
I'd like to remove some elements such as <footer> tag, menu row etc. on pages where body has unique classes like: 'shop_news_list' and 'shop_news'. The site is based on Smarty. I've tried to put those elements I want to delete in between something like this:
{if !($body_class == 'shop_news_list' || $body_class == 'shop_news')}
<footer>
<div class="innerfooter container row">
...
</div>
</footer>
{/if}
However it doesn't work or makes an element disappear from every page. Is there any other way I can do this or maybe you know how can I properly check if body has specific class. (I can not create new templates to use them on different pages).
I'm new coding and Could someone tell me what i am doing wrong.
I want to see if a image exists in a folder but it won't display the image if it exists.
{assign var="backimg" value="/thumbs/backgrounds/movie_bg/`$mov.title|lower|replace:' ':'_'`.jpg"}
{ if file_exists($backimg) }
<div class="container_inner"
style="background:url(/thumbs/backgrounds/movie_bg/{$mov.title|lower|replace:' ':'_'}.jpg)no-repeat center;">
{else}
<div class="container_inner">
{/if}
Could someone tell me if there is anything wrong with my code.
Smarty is a templating language. You don't write PHP code into a template like that. You do the logic in the PHP code that calls the template, assigning whatever values are needed to render the page correctly to the template, and then render the template.
// In the PHP code.
// (Simplified. The actual code to initialize Smarty will usually be more complex.)
$smarty = new Smarty();
$smarty->assign("file_exists", file_exists('/file/path'));
$smarty->display('mytemplate.tpl');
// In the 'mytemplate.tpl' template file.
{if $file_exists}
<p>File exist!</p>
{else}
<p>File doesn't exist</p>
{/if}
I've implemented smarty on my CI installation via this tutorial: http://www.coolphptools.com/codeigniter-smarty
It works fine, except that the header and footer is loaded by including the files from within the template.
ie.
{include file="header.tpl" title="Example Smarty Page" name="$Name"}
...
{include file="footer.tpl"}
Is there a way to load them from the controller or from the Smarty library class?
To give a clearer example of what I want; Without a templating engine I would just extend the view method via a custom loader.
eg.
class MY_Loader extends CI_Loader {
function view( $template, $data = array(), $return = false ) {
$content = parent::view( 'header', $data, $return );
$content .= parent::view( $template, $data, $return );
$content .= parent::view( 'footer', $data, $return );
if( $content )
return $content;
}
}
This has always worked for me, but now I'm trying out smarty and I could not for the life of me figure out how to make it work like this one.
If anyone could point me to the right direction. That'd be great.
PS. Apologies if this has already been answered before, I've been Googling this for the past 2 hours and I can't seem to find anything. My PHP skills are intermediate at best.
I'm no expert but I did have to go through this not too long ago.
What I did is something like this:
header.tpl
<html>
<head>
</head>
<body>
content.tpl
{include file="header.tpl"}
{include file="$content"}
{include file="footer.tpl"}
footer.tpl
</body>
</html>
Then you could just have smarty call content.tpl always and pass the actual body content through $content.
Like I said, though, I'm not expert so the syntax might be off and there might be a more "correct" way of doing this, but I think the idea is there.
Hope that helps.
You should use the {extends} syntax to take advantage of template inheritance.
Start with your base template file (we'll call it template.php). This file will include your header and footer code, and will specify the location for the main content (and any other blocks of template code you'd like to specify, such as an aside for instance).
(I'm using really bare bones HTML here, just for example purposes. Please don't code like this.)
template.php:
<html>
<head>
<title>{$title|default:'Default Page Title'}</title>
<meta>
<meta>
</head>
<body>
<header>
<h1>My Website</h1>
<nav>
<!-- Navigation -->
</nav>
</header>
<section class="content">
{block name="content"}{/block}
</section>
<footer>
© 2013 My Website
</footer>
</body>
Then, your individual pages would {extend} the main template file, and specify the necessary content for all of the blocks. Note that you can make blocks optional and with default values, so there is no requirement to fill all blocks (unless you code it that way).
content_page.php:
{extends file="template.php"}
{block name="content"}
<h2>Content Page</h2>
<p>Some text.</p>
{/block}
you can user following way to include smarty tpl view in your controller:
$this->smarty->view('content.tpl')
and header.tpl in content page:
{include file='header.tpl'}
I know that the first part of this is subjective, but I'd like to hear some different techniques people use. This is a two part question: what do you use for complex multiline strings in PHP? And, can I use a composition type of relationship with smarty?
Question 1: I know there is heredoc and the "." operator. I'm looking for fresh, more readable ideas if there are any.
Question 2: To be more specific, here is what I would like to do with smarty.
Say I have a template, base.tpl:
<html>
<head><title></title></head>
<body>
{$main_content}
</body>
</html>
Can I chain templates, i.e. another template that represents $main_content, say main.tpl:
<div id="header">$header</div>
<div id="container">
<h1>{$first_header}</h1>
<p>{$first_paragraph}</p>
<h1>{$second_header}</h1>
<p>{$second_paragraph}</p>
I want in whatever.php to load one template into the other, so i.e.:
// ... including smarty and all other boiler plate things ...
$smarty -> assign('first_header', "Foo");
$smarty -> assign('first_paragraph', "This is a paragraph");
$smarty -> assign('second_header', "Bar");
$smarty -> assign('second_paragraph', "This is another paragraph");
$main_content = $smarty->load('main.tpl');
$smarty -> display('base.tpl');
I know that there is "template inheritance" in smarty, but I'm not familiar with it. Can it give me similar functionality to this?
Note: I think my biggest problem with heredoc is that I can't get syntax highlighting for html (if i specify html in the heredoc string). Without the highlighting, the html that I want to pass through smarty is much harder to read, which kind of defeats the purpose of smarty.
You'll want to use {include} to call templates (fragments) within a template.
http://www.smarty.net/docsv2/en/language.function.include.tpl
<html>
<head>
<title>{$title}</title>
</head>
<body>
{include file='page_header.tpl'}
{* body of template goes here, the $tpl_name variable
is replaced with a value eg 'contact.tpl'
*}
{include file="$tpl_name.tpl"}
{include file='page_footer.tpl'}
</body>
</html>
Passing variables into included templates:
{include file='links.tpl' title='Newest links' links=$link_array}
{* body of template goes here *}
{include file='footer.tpl' foo='bar'}
In terms of multi-line strings, I tend to use this pattern:
$my_string = "Wow, this is going to be a long string. How about "
. "we break this up into multiple lines? "
. "Maybe add a third line?";
As you said, it's subjective. Whatever you feel comfortable with and as long as its easily readable...
I found some documentation on template inheritance this morning...
To expand on my example above, you can have a base layout (base.tpl)
<html>
<head><title>{$title|Default="title"}</head>
<body>
<nav>{block name=nav}{/block}</nav>
<div id="main">{block name=main}Main{/block}</div>
<footer>Copyright information blah blah...</footer>
</body>
</html>
You can extend a template and override blocks now with the new version of smarty (home.tpl)
{extends file=base.tpl}
{block name=nav}
<ul style="list-style:none">
{foreach $links as $link}
<li>{$link.txt}</li>
{/foreach}
</ul>
{/block}
{block name=main}
{foreach $paragraphs as $p}
<h2>{$p.header}</h2>
<p>{$p.content}</p>
{/foreach}
{/block}
http://www.smarty.net/inheritance
I am currently working on moving an expression engine site from one server to another and i noticed one issue i am having a hardtime debugging. When i upload an logo image all seems fine but the index.php page that the logo is displayed on it has this code
{embed="shared/head"}
<body class="{if segment_1 == ''}home{if:else}{segment_1}{/if}">
<div id="page" class="container">
<div class="span-22 prepend-1 append-1 last">
{embed="shared/masthead"}
{if logo !=''}
<div class="news_item_logo">
{organization}
{if link}<img src="{logo}" width="130" alt="{title}" />{if:else}
<img src="{logo}" width="130" alt="{title}" />{/if}
{/organization}
</div><!-- /.news_item_logo -->
<ul>
<li><h3>{title}</h3></li>
<li>{pub_date}</li>
{organization}
<li>{if link}{/if}{exp:php_text_format type="lowercase"}{if url_text != ''}{url_text}{if:else}{name}{/if}{if link}{/exp:php_text_format}{/if}</li>
{/organization}
<li>{if file}PDF{/if}{if web_link !='' AND file !=''} | {/if}{if web_link}HTML{/if}</li>
</ul>
{if:else}
<ul class="no_logo">
<li><h3>{title}</h3></li>
My question is this, I see curly brackets {} around if statements and i want to know first what language it is and second is there a way to debug like php print_r() because the code always goes to the else with the no_logo class and i want to know what and how i can test these variables "segment1" and "logo" and "organization" and "url" How do and where do i inspect these variables
You can gain some info about the given variables and values in the template using the following within your index.php:
<?php
$EE = get_instance();
var_dump($this->EE->TMPL);
?>
Note that PHP must be enabled in templates for that to work (see PHP in Templates).
{embed="shared/head"} - include the template head from the template group shared
<body class="{if segment_1 == ''}home{if:else}{segment_1}{/if}">
if the URI segment (EE/CI works with segments eg site.com/segment1/segment2/xxx) is empty (you are on the home page (www.site.com), then add no body class.
else, the user is on a page (in EE this is a template group), so set the class to be the name of the template group.
site.com/about-us produces class="about-us" - handy for page specific styling.
{embed="shared/masthead"} - include masthead
and so on.
The rest are conditionals to check if the variables have values, and outputs them
I presume you're using EE2.0, I'm not sure what {organizaton} is specifically, but that style:
{organization} {foo} {/organization}
in code igniter at least, is generally the equivalent of a foreach or looping through a recordset:
foreach($organizations as $organization) { // do something }
This is written in Expression Engine's own templating language.
You would have to check the documentation to see whether there is any way to debug variables.
Possibly helpful links:
Quick Reference Chart
PHP in Templates