tags:

views:

139

answers:

2

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();
A: 

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"}
karim79
thats OK but I don't know if I am logged until 500 lines into code. That means I would have to bury my "output header" deep in the user validation code, just before the "logon" screen
TMP File guy
Is it possible to output the "not logged in" header up front, then clear it if not the appropriate version?
TMP File guy
@TMP - that seems like a workaround to an architectural problem. You should consider revising your solution such that all business logic is executed *prior* to any output.
karim79
A: 

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.

Cfreak