Forum Moderators: coopster
Example...
a profile page looks something like this.
<?php
require('class.php');
require('header.php');
$profile = new Profile();
$userProfile = $profile->GetUserProfile($userID);
echo $userProfile;
$class = new Posts();
$posts = $class->GetUserPosts($userID);
echo $posts;
require('footer.php');
?>
And the main page looks something like this
<?php
$class = new Posts();
$posts = $class->GetAllPosts();
echo $posts;
?>
where the profile class would take a user id and output the users profile, already formatted in html.
And the posts class has functions to return a determined number of posts already formatted in an html list
Thanks
Try making "templates". Call the templates under specific conditions. They are pre populated with whatever you require. (eg. where user=someuser if have posts get posts how many sort asc)
Sounds like your requirements are similar to what WordPress offers. You can call users posts anywhere with a single line. Hit the support forums there for more info. May want to give it a look see. "wordpress.org". You can have it up and running in less than five minutes, and it is free. I use it as a cms for many sites right now on my shared server. Saves A LOT of time and easy to customize. There is even a user profile plugin that is easy to mod to suit your needs. You can also post/edit remotely using windows live writer or via email.
Just a suggestion.
As far as using html in functions, I see no issues if the functions can only be called via your script. WordPress uses functions in the templates as well. I use them frequently to create menus and for "switches".
You may be able to get "inspiration" from snippets of code from WordPress to use in your app as well.
Hope my reply helps a little..
First off... the idea of outputting HTML is "bad" is false. At some point, you need PHP to output HTML. You have a good approach, where your functions "handle" data. But what I would recommend is maybe just creating some helper functions to handle your output... ie:
function buildPosts()
{
$class = new Posts();
$posts = $class->GetUserPosts($userID);
echo $posts;
}
Then in your HTML file (or such), all you gotta do is:
<?php buildPosts(); ?> Where you want your posts to appear. But that is my opinion.
As noted above... the idea of "templating" your design is always a great idea. Say you have tons of pages such as profiles, posts, members, groups, etc etc (example). And they all look like this:
<?php
require('class.php');
require('header.php');$profile = new Profile();
$userProfile = $profile->GetUserProfile($userID);
echo $userProfile;
$class = new Posts();
$posts = $class->GetUserPosts($userID);
echo $posts;
require('footer.php');
?>
You repeat a lot of the same code (ie, including the header/footer/etc). After years of design and development you'll eventually loath repeating the same chunk of crap, because one day you'll need to update it, and when it is spread over multiple files, multiple time, multiple places... it is a pain to manage.
Though your approach of putting the header/etc all in their own files/functions is a great approach! You should also consider creating a "template" or "shell" page where all that is setup for you, and then the "content" area is filled in dynamically.
Example:
template.php
<?php
require('class.php');
require('header.php');
/*Start of Content Area*/
if (file_exists($thisFile)) { include("{$thisFile}"); }
else { echo "<p>Page not found.</p>"; }
/*End of Content Area*/
require('footer.php');
?> Then just setup your code to include the template and set the 'thisFile'. How you do this part, is a bit trickier.
What I've learned to do:
Setup URL rewriting on the server and have it pass all requests (for files that do not exist) to a single PHP script (ie: '/go.php'). This file then analyzes the request URI to determine what to do. It then sets up whatever files I need by simply including files as needed. Look into URL rewriting, it is pretty powerful when you combine it with PHP in terms of structuring your site and files!
Note that it is a lot of work to setup; but can ultimately save you TONS of time when it comes to managing or making a simple content-based, or even dynamic, website.
Also, I read about having separate template files, using while, for, and foreach loops. i also heard of using placeholders within the template and then str_replace to replace the placeholders with the actual data. I dont mean to be needy, but if somebody could post an example of how this would be done using foreach, and the best way to do it. Like, where would I do the str_replace, within each loop, or afterwards?
class Template{
function Display($file, $info = array()){
ob_start();
include($file);
$output = ob_get_clean();
return $output;
}
}
I'm also a little confused as to whats going on within your template files. currently, I have all of mine split up in different parts like this...
user_profile.php
<div>
<h2><?php echo $info['name']; ?></h2>
<p><?php echo $info['description']; ?></h2>
</div>
user_articles.php
<?php foreach($info as $post){ ?>
<div>
<h2><?php echo $post['title']; ?></h2>
<p><?php echo $post['body']; ?></h2>
</div>
<?php } ?>
and then my actual page might look something like this...
require('header.php');
require('template.class.php');
$user_id = isset($_GET['uid']) ? $_GET['uid'] : 0;
$user_info = Get_User_Info($user_id);
$user_articles = Get_User_Articles($user_id);
$template = new Template();
$user_profile = $template->Display('user_profile.php', $user_info);
$user_articles = $template->Display('user_articles.php', $user_articles);
echo $user_profile;
echo $user_articles;
require('footer.php');
I saw in your example you didnt include your header, or footer, and you used the show() function only once. Am i doing something wrong, or rather is there a better way i could do this. I have a feeling that your class builds the template on the fly, instead of simply getting and displaying the template.
I know CyBerAlien mentioned URL rewriting and also mentioned using templates and URL rewriting, which I think I've heard of and dabbled in when I created an Error class to handle 404 errors, but how would that help with templates exactly, i dont see the connection
Call this test.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="en" xml:lang="en" xmlns="http://www.w3.org/1999/xhtml">
<body>
<form name="myForm" method="post">
<!-- You only show() things once. To show in different spots you have to use the
begin and end blocks like so. Then you add a variable -->
<!-- BEGIN Block1 -->
{initialMessage}{msg1}<br />{msg2}<br />
<!-- END Block1 -->
Please click one<br />
<input type="submit" name="messageOne" value="Set Message One" /><br />
<input type="submit" name="messageTwo" value="Set Message Two" /><br /><br /><br />
<!-- Here is a little more complex example -->
<!-- BEGIN table -->
<table>
<tr>
<td>Row 1 column 1
</td>
<td>Row 1 column 2
</td>
</tr>
<tr>
<td>Row 2 column 1
</td>
<td>Row 2 column 2
</td>
</tr>
<tr>
<td>{thirdRow}
</td>
<td>Row 3 column 2
</td>
</tr>
<!-- Here we are just adding another row to the table and not the whole thing -->
<!-- BEGIN newRow -->
<tr>
<td>{tableMessage}
</td>
<td>{secondTableMessage}
</td>
</tr>
<!-- END newRow -->
</table>
<!-- END table -->
<input type="submit" name="table" value="Add the Table" /><br />
<input type="submit" name="addRow" value="Add a row to the table" /><br />
<input type="submit" name="reset" value="Reset the table" /><br />
</form>
</body>
</html>
And call this test.php
<?php
require_once("HTML/Template/IT.php");
$template = new HTML_Template_IT("./");
$template->loadTemplatefile("test.html");
//start a session just read through to see why
session_start();
//initialize this if it hasn't already been set
if(!(isset($_SESSION['counter']))){
$_SESSION['counter'] = 1;
}//if !isset
//first off we have to set the initial message
//notice I set it to nothing. You don't have to do that
//its just that you have to set at least one variable
//to load the page. So if your page looks correct on the load
//then just set one to nothing. If you want to load data on the page
//load from the db then just set your information in it
$template->setCurrentBlock("Block1");
$template->setVariable("initialMessage", "");
$template->parseCurrentBlock();
//if they click the message one button
//then we will set message one
if(isset($_POST["messageOne"])){
$template->setCurrentBlock("Block1");
$template->setVariable("msg1", "You clicked message one.");
$template->parseCurrentBlock();
}//if isset messageOne
//if they click the message two button
//then we will set message two
if(isset($_POST["messageTwo"])){
$template->setCurrentBlock("Block1");
$template->setVariable("msg2", "You clicked message two.");
$template->parseCurrentBlock();
}//if isset messageOne
//if they clicked add a table we will add it
if(isset($_POST['table'])){
$template->setCurrentBlock("table");
$template->setVariable("thirdRow", "Row 3 Column 1");
$template->parseCurrentBlock();
}//if isset table
//if they clicked add a row we will keep track
//of how many times they have clicked it with a
//session varaible to add all of the rows
//you will notice in the table that the
//third row first column is missing becase
//we don't set that but since this block
//is nested in the table block it still sets
//that whole block
if(isset($_POST['addRow'])){
$tempCount = 1;
while($tempCount <= $_SESSION['counter']){
$rowCount = $tempCount + 3;
$template->setCurrentBlock("newRow");
$template->setVariable("tableMessage", "Row $rowCount Column 1");
$template->setVariable("secondTableMessage", "Row $rowCount Column 2");
$template->parseCurrentBlock();
$tempCount++;
}//while
//add one to the counter
$_SESSION['counter'] = $_SESSION['counter'] + 1;
}//if isset addRow
if(isset($_POST['reset'])){
$_SESSION['counter'] = 1;
//load the original table
$template->setCurrentBlock("table");
$template->setVariable("thirdRow", "Row 3 Column 1");
$template->parseCurrentBlock();
}//if isset reset
//notice we only put this once
$template->show();
?>
Another question I have is about the forms. When I first started learning PHP, I read it was best to simply use the same page to display and handle the form. I recently read that Its best to separate the two (and any other piece of html from php code), but I can't seem to understand why that would be the best for a form. It seems that just handling the code in PHP above, closing the php braces, and then displaying the html form would be best. Any ideas (and small examples) would help. thanks again to andrewsmd
Lets say i have a class like so...
class Template{
$private $output = '';
public function Load_Template($template){
ob_start();
include($template);
$this->output = ob_get_clean();
}
public function Replace($data){
$this->output = str_replace(array_keys($data), array_values($data), $this->output);
}
public function Display($add_footer = true){
echo $this->output;
}
}
This would work for a simple Template like...
<div>{username}</div>
But what would be the best way to do it with loops in my template. Lets say something like
<ul>
<li>{username}</li>//Loop this line for each user
</ul>
Im working on a Replace function that will replace my placeholders with their values, which would work just fine with regular templates, but im comfused about how I would do that with loops.... As usual, thanks for even reading
Here is the html
<!-- BEGIN loopBlock -->
<ul>
<li>{loopMessage}</li>
</ul>
<!-- END loopBlock -->
and here is the php
//i just did a simple forr loop
//however, wherever you get your username
//loop blocks just put this code in that loop
//instead of my static for
$template->setCurrentBlock("loopBlock");
for($i = 0; $i < 10; $i++){
$template->setVariable("loopMessage", "Item $i");
$template->parseCurrentBlock();
}//for
Hope that helps let me know if you need anything else. If you paste the loop of how you get your usernames I could help you out more.
So $this->Get_Local_Users('08901', 5); will return something like this
$users = array(0 => array('name' => 'john', 'age' => 12, 'zip' => '08873'), 1 => array('name' => 'billy', 'age' => 15, 'zip' => '08854'));
you get the point right? the arrays look like this...
$users[0]['name'] == john
$users[0]['age'] == 12
$users[0]['zip'] == 08873
$users[1]['name'] == billy
so, what i have right now is this
<ul>
<?php foreach ($users as $user): ?>
<li><?= $user['name']; ?> - <?= $user['age']; ?></li>
<?php endforeach; ?>
</ul>
you mentioned that this can get real messy, but I dont understand how I would be able to do it "easily" any other way. I looked at a few template engines, and I saw that smarty creates there own language to parse the templates, and savant just uses php as its own template language (just as i did above).
If I could understand how to handle loops, I could easily just use placeholders like {username} within my templates.
Thanks again
foreach($users as $user){
$template->setVariable("loopMessage", "Name: {$user['name']} - Age: {$user['age']} - Zip: {$user['zip']} ");
$template->parseCurrentBlock();
}//for
For example, I've seen people mention doing this with their templates
<h1>{name}</h1>
and then something like this to fill in the {name} placeholder.
$data['{name}'] = 'Michael';
$output = str_replace(array_keys($data), array_values($data), $output);
Then the final output would read
<h1>Michael</h1>
But, I dont get how to do this within loops, and I'm not understanding whats happening within your class functions, unless your using a 3rd party template engine?
class Template{
$private $output = '';
public function Load_Template($template){
ob_start();
include($template);
$this->output = ob_get_clean();
}
public function Replace($data){
$this->output = str_replace(array_keys($data), array_values($data), $this->output);
}
public function Display($add_footer = true){
echo $this->output;
}
}
Heres my user profile template. user_profile.php...
<div>
<h1>{name}</h1>
<ul>
<li>{age}</li>
<li>{zip}</li>
</ul>
</div>
Heres how I call it...
$user = array('{name}' => 'john', '{age}' => 12, '{zip}' => '08873');
$template = new Template;
$template->Load_Template('user_profile.php');
$template->Replace($user);
$template->Display();
Everything above i understand completely, but I dont really know how I would do this using loops, unless I did something like....
user_list.php
<li>
<h1>{name}</h1>
<b>{age}</b>
<b>{zip}</b>
</li>
call it like this...
$users = array(0 => array('name' => 'john', 'age' => 12, 'zip' => '08873'), 1 => array('name' => 'billy', 'age' => 15, 'zip' => '08854'),
2 => array('name' => 'Bill', 'age' => 12, 'zip' => '08873'), 3 => array('name' => 'Joe', 'age' => 15, 'zip' => '08854'));
echo '<ul>';
foreach($users as $user){
$template->Load_Template('user_template.php');
$template->Replace($user);
$template->Display();
}
echo '</ul>';
I just dont understand what exactly is happening within your template engine... If you've already answered this question and I just missed it, I apologize for wasting your time.