It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 12 years ago.
PHP and HTML codes are all messed now in my application. What should I do? Something like template engine? I want to program it myself. It is with purpose to learn PHP.
Here's my view rendering function.
<?php defined('APPPATH') or die('no direct script access');
class ViewFileMissing extends Exception {}
function renderView($viewname, $data)
{
$filename = APPPATH.'/views/'.$viewname.'.php';
if (!file_exists($filename))
{
throw new ViewFileMissing($viewfile);
}
extract($data, EXTR_SKIP);
ob_start();
require($filename);
return ob_get_clean();
}
It can be used with a template like
<html>
<head>
<title><?php echo $title ?></title>
</head>
<body>
<p><?php echo $paragraph; ?></p>
</body>
</html>
It can then be called like
$data = array('title' => 'This is a title', 'paragraph' => 'This is a paragraph')
$html = renderView('viewname', $data)
It works by creating a local variable for each of the elements of the data array, turning on output buffering, requiring the template file, which outputs all of the html into the buffer and then clearing the buffer and returning the output. So all of the rendered html is now in a string that can be echoed.
The html is just for example, it wouldn't validate. Also note that this is the only legitimate use of extract that I have ever seen.
You could use MVC.
M - Models
Specifies the data to be shown and/or handled by the views and controllers.
V - Views
This is your actual HTML with the only PHP is the code that replaces itself with the data provided by the controller.
C - Controllers
Processes the browser's request, fetches the data from the model and passes it to the view.
Example
models/post.php - model - blog post (dummy data return, you could use a database, web service, whatever)
<?php
function post_with_id($id) {
$post = array();
$post["id"] = $id;
$post["title"] = "Sample post " . $id;
return $post;
}
post.php - controller - processes request, navigate to e.g. /post.php?id=3
<?php
require_once('models/post.php');
$post = post_with_id((int)$_GET["id"]);
include('views/post.php');
views/post.php
<h1><?php echo $post["title"]; ?></h1>
This really keeps your code clean. Just alter your model to fetch other data, from a database or from files for example and you have your dynamic content!
This is just a very simple example of MVC. Look at Wikipedia's article about it. Have fun!
Use MVC -- Model, View, Controller. Models contain application logic and database access, and overall data handling. Views contain HTML code and are like templates. Controllers are the URLs the user goes to, and include the models to retrieve/set the data and the views to display it.
Maybe look at some applications that use MVC and see how they're structured.
The simplest, and fastest, way to separate your presentation (HTML) from your logic (PHP) would be to use Smarty Templating Engine. It's a half-step between running hybrid files (where the logic and the presentation are mashed together) and a fuill MVC solution. But I would think that it would be easy to go that way, should you want to down the track.
Related
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
I have a website I am making as a school project, and it appears I have jumped into something a bit too deep. I'm using PHP to create a page for each array object. In each page, I want to personalize the contents to match the page. For example, I have a page that gets created named Darryl and it's going to contain all my images. Other pages will be created and the contents of those pages will be created dynamically depending on the page.
What I am trying to do, is to change the img src using PHP and use a counter to make different images pop up. This is incredibly hard for me to explain.
I have this line of html code which contains the php(Which determines which images get shown:
<td><img style="width:11em;" class="magnify" src="<?php print $imgSrc; ?>"/><br><?php print $pageName; ?></td>
The part i am having issue with is the " print $imgSrc; " part. This is the area where my php will create the src path. It uses this variable $imgSrc to get the correct path.
That variable is:
$imgSrc = "images"."/".$pageName."/".counter();
Which writes the
It looks like you're confused about what a function is or perhaps when it gets executed. If this is all the code you have on your page:
$imgSrc = "images"."/".$pageName."/".counter();
<td>
<img style="width:11em;" class="magnify" src="<?php print $imgSrc; ?>"/><br>
<?php print $pageName; ?>
</td>
Then $imgSrc is only ever written to once. So whatever counter() does, it only does once. You could wrap the whole thing in a for loop and do away withe the counter() call. You could remove the local variable of $imageSrc and make the attribute defined on the fly, like so:
<td>
<img style="width:11em;" class="magnify" src="<?php print "images"."/".$pageName."/".counter(); ?>"/><br>
<?php print $pageName; ?>
</td>
Then if the counter() function is stateful itself (as in, it returns a different value each time you call it), you're all set.
You can make a stateful function like the following:
$counter_var = 0;
function counter() {
global $counter_var;
return $counter_var++;
}
But globals are frowned upon, because the create hard to trace side effects (and other reasons). Most people would tell you to use a for loop. I only mention it because it looks closer to what you were trying to do in your original code.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I am using the template parser class in CodeIgniter to give the view (MVC) a designer-friendly look. I have a series of posts that I want to display, but on the front page I only want part of a post to show (first 200 characters) followed by a ... "Read More" link.
It is outputting the posts, but seems to be ignoring the PHP substr() function bc the text comes out full-length.
Inside the model class:
function __construct()
{
parent::__construct();
$this->load->library('parser');
$this->load->model('MPosts');
}
function index() // BASE_URL
{
$data = array("article_posts" => $this->MPosts->get_posts());
$this->parser->parse('VPosts', $data);
}
Inside the view:
<body>
{article_posts}
<h2>{title}</h2>
<p><?=substr("{post}", 0, 200);?>...</p>
<p>Read More</p>
<hr />
{/article_posts}
</body>
Since you are using a MySQL query to fetch the articles you can always use SUBSTRING(article_column_name,1,200) to only grab the first 200 chars, basically substr()
See: https://dev.mysql.com/doc/refman/5.0/en/string-functions.html#function_substring
Inside the parser->parse() code:
CI first passes your template through the load->view() processor, just like a regular view (so it executes PHP code inside your template),
then it passes it through the "{pseudovar}-replacer".
At this point I'm sure you understood the problem: substr() is applied to the string "{post}"
I can think of these options for your case:
do the substr() controller-side, probably the fastest solution to fix your issue
remove the Parser layer and use plain ol' PHP code, which is so fine
use a third-party über heavy full-featured template engine
Try echo instead of ?= .
People tend to leave code to load (model) libraries in constructors of the controller in which user-defined functions will invoke calls to user-defined functions implemented in model files.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
In creating my own template, there seems to be two ways of displaying my body content using PHP and HTML. Which method tends to be the preferred, or most correct, method?
Is there an industry standard? For example - if I showed my code to Facebook, is there a certain method that the person hiring me would be looking for?
Both of them are clumsy at first to write.
Method #1
<?php
//Begins with <body>
templateGetAboveContent();
//Begin unique content
?>
<h1>Example Header</h1>
<div id="article_container">
<?php
if ($row = mysql_fetch_assoc(mysql_query($get_article_sql))
{
?>
<div id="article"><?php echo $row['article_content'];?></div>
<?php
}
templateGetBelowContent();
?>
Method #2
<?php
$body = "";
$body .= "<h1>Example Header</h1>";
$body .= "<div id=\"article_container\">";
if ($row = mysql_fetch_assoc(mysql_query($get_article_sql))
{
$body .= "<div id=\"article\">" . $row['article_content'] . "</div>";
}
templateGetDisplayContent($body);
?>
In Method #2, templateGetDisplayContent() would simply echo $body; where it should be, between the displayAbove and displayBelow code.
Both methods apparently has nothing to do with templates at all.
First one is closer but seeing a word "mysql" in the template one can say that is failed attempt for sure.
You have to make a strict separation between data processing part and data displaying part.
There should be not a single symbol sent to the browser until all data got ready.
So, make your site consists of pages, page templates and main template.
Once your script called, it have to process data, and then load site template, which, in turn, will load page template.
An example layout is going to be like this:
a page:
<?
//include our settings, connect to database etc.
include dirname($_SERVER['DOCUMENT_ROOT']).'/cfg/settings.php';
//getting required data
$DATA=dbgetarr("SELECT * FROM links");
$pagetitle = "Links to friend sites";
//etc
//and then call a template:
$tpl = "links.tpl.php";
include "template.php";
?>
it outputs nothing but only gather required data and calls a template:
template.php which is your main site template,
consists of your err.. templateGetAboveContent() and templateGetBelowContent():
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>My site. <?=$pagetitle?></title>
</head>
<body>
<div id="page">
<? include $tpl ?>
</div>
</body>
</html>
and calls the actual page template:
<h2><?=$pagetitle?></h2>
<ul>
<? foreach($DATA as $row): ?>
<li><?=$row['name']?></li>
<? endforeach ?>
<ul>
This would be a REAL use of templates.
Note that the main site template is able to display variable texts depends on the current page contents.
Is there an industry standard?
No. There are several standards.
Escaping from HTML is closer to one of them, but still you are using it wrong way.
Any programming language is built to give flexibility to the developer. They're just "toolkits" provided to programmers and it's up to the programmers to implement stuff (and invent stuff) they want done. As far as i know, there are a lot of templating engines (both built in to frameworks and standalones) out there that simplify rendering of pages but sacrifice that flexibility for the ease of use.
You mention Facebook (and surely figured out they use PHP). However, what you don't know is that they have developers that build their own API which may include templating for their pages - in other words, their own implementation.
All in all, it depends on what you are going to do and what tools you use at the moment. You should try exploring using frameworks and other tools. You will learn a lot on how each of them implement their templating methods (sooner or later you will lean to one or two of these methods).
personal suggestion: try mustache
There isn't a 100% correct answer to this, as both will ultimately get you the goal you need.
Using Method 1 though will likely allow you to better interact with the templates in the event they need to be updated.
Especially if another party like a designer is involved, who is providing static HTML.
You could easily go into that and just add the PHP tags/code where need be.
Personally, I think the first example is simple and straight to the point. And I think someone who would be hiring you would think the same. Plus, keeping all the body content in a variable would be a hassle to use across a whole site.
I'm relatively new to php, and I'm working on a project using a mysql database. The project consists of users being able to write posts, which are then shown in a list format. The problem is, the posts are shown in different locations on the site, like the index (main) page, and the users profile page. Similar to twitter if you're confused. My question is, what is the best way to display the posts? Currently I'm using a class that I created. It has functions to retrieve posts from the database, save them all in a multidimensional array. Then another function in the class formats the entire list using foreach, and then returns the formatted HTML list of posts. All I have to do is echo what is returned. But I read somewhere that it's bad practice to write functions (especially class functions) that output HTML. What would be the best way to do this, without having to rewrite the same code on every page the posts are shown. Is it really bad practice to use HTML in functions?
Example...
a profile page looks something like this.
<
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
<
$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.
Should I keep everything in the class, or is there a better way?
Thanks
Well, if you're not using an MVC framework of some kind, then I would say that having functions that output HTML isn't going to kill anyone.
Generally however, it's helpful to separate HTML from logic, and this is usually done by creating an HTML template and template fragments with interspersed PHP. Something like this:
<div>
<h1><?php echo $title; ?></h1>
</div>
You could then set up a $title variable (and others), and include('title_fragment.php') to output that bit of HTML. You can extend this to work with entire pages, making it so that your code only has to deal with small amounts of data that get passed to the template.
When it comes time to make changes to the page layout or look, you don't have to go hunting through the code to find the bits of generated HTML... you can go straight to the template files.
This is important for maintainable design as well as code, and it makes it easier to produce other output types later on.
With PHP, one of the simplest libraries for separating the two is Smarty templates. Using Smarty (or any other templating library), you can write an HTML file with the layout and some simple loops or other constructs, and then render that template using a data structure. At the very least, I would suggest altering your class to utilize a template and produce output that way, rather than a mish-mash of print or echo statements with a bunch of HTML in them.
I'd even shy away from #zombat's solution of echo statements in HTML fragments, they quickly become ugly.
Example Smarty template to achieve something like what you want:
{section name=i loop=$posts}
<li>{$posts[i].author} — {$post[i].text}</li>
{/section}
And some PHP supporting code:
// Instantiate Smarty object
$smarty = new Smarty();
// Assign a hash of data
$smarty->assign('posts', array(
array('author' => 'Jim', 'text' => 'Hi this is my post!'),
array('author' => 'Sally', 'text' => 'My first post to the system')
)
);
// Use the file with the above template in it
$smarty->display('posts.html');
The part where you assign data to the template should probably be done via some programmatic means to convert your list of class objects into a list of hashes.
This way you can easily change the way the output looks just by editing the HTML template and you don't have to worry about touching any code to change the output.
Your class should ideally provide the data only. Use another PHP file or generic class to output HTML, so later you could output e.g. XML, JSON, etc from the same data class. This separates your data processing (model/controller) from your data representation (view).
I would disagree with using a template engine like Smarty. PHP is a template engine.
You can use output buffering. It's helping to build your templates and not be forced to process data in the display order.
<?php
$posts = take_data_from_class();
ob_start();
require_once('path/to/posts.php');
$html_posts = ob_get_clean();
// you can do the same with other parts like header or footer
ob_start();
require_once('path/to/header.php');
$header = ob_get_clean();
ob_start();
require_once('path/to/footer.php');
$footer = ob_get_clean();
?>
In posts.php you can display the posts:
<? foreach ($posts as $p) { ?>
<div class="...">
post data here
</div>
<? } ?>
Now, to display the whole thing:
<?php echo $header . $html_posts . $footer; ?>
More at http://us3.php.net/manual/en/book.outcontrol.php
Enjoy!
Im not familiar with Smarty at all...how exactly does that work, and what are the benefits of using a smarty vs. just creating functions to take large amounts of data and return html containing that data just to be echoed later?
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking us to recommend or find a tool, library or favorite off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it.
Closed 9 years ago.
Improve this question
I'm looking for a lightweight, PHP based, layout framework. Like how the Zend Framework, uses layouts, I would like to create a layout template and include only the content for the necessary pages.
<html>
<head>
<title><?= $pageTitle ?></title>
</head>
<body>
<?= $content ?>
</body>
</html>
Anyone know of anything that does this? I would use the Zend Framework, but it's just too much for what I want to achieve.
I vote for PHP. (PHP is a templating engine.)
function template($file, $vars) {
ob_start();
if(count($vars) > 0) { extract($vars); }
include 'views/'.strtolower($file).'.php';
return ob_get_clean();
}
Which, incidentally, lets you do the following.
echo template('layout', array( 'content' => template('page', $myData) ));
Should you even bother using another templating/layout engine at all, when PHP itself can suffice in a mere 6 lines?
Edit:
Perhaps I wasn't clear with how this works.
template() is called with the name of the template (subdirectories for organization work too) with an array object as the second parameter. If the variables given aren't blank, like template('index',null) is, then the array is treated as an associative array: and every key becomes a variable containing the value.
So the logic becomes:
template('my_template', array(
'oranges' => 'apples'
));
And "views/my_template.php" is:
<html>
<head>
<title>Are apples == <?= $oranges ?>?</title>
</head>
<body>
<p style="color: <?= $oranges == 'oranges' ? 'orange" : 'darkgreen' ?>">
Are apples == oranges?
</p>
</body>
</head>
So, every time the variable $oranges is used PHP gets the data that was exported from the array, $vars['oranges'].
So all the output is then taken by ob_get_clean() and returned as a string. To output this string just echo or print, or assign it to an array to be passed as content to the layout. If you understand this, then it is very easy to take what I've written and make a layout out of it, or pages with logic that output JSON even.
I would advise you to experiment with this answer before discarding it. It has a tendency to grow on you.
Edit 2:
As requested I'll show the directory layout that my project would use. Do note that other MVC frameworks use a different structure. But, I like the simplicity of mine.
index.php
application/
framework.php
controllers/
welcome.php
views/
template.php
index.php
For security purposes, I have an .htaccess file that routes every request, except those to js/ or css/, to the index.php script, effectively making my directories hidden. You could even make the CSS via a template if you wished, which I've done, for the use of variables, etc.
So, any call made to template('template', array()) will load the file ./views/template.php automatically. If I included a slash in the name, it becomes part of the path, like so: ./views/posts/view.php.
Edit 3:
thanks for your update. So you must have some code in your index.php file that routes the requested url to the appropriate controller, correct? Could you show some of this? Also, it doesn't look like your views mirror your controller directory. Can you explain a little more how urls map to controllers and/or views? What do you have in framework.php? What does it do? Thanks!
The code I've shown is a tiny excerpt of my private framework for web development. I've talked already about potentially releasing it with a dual-license, or as donation-ware for commercial use, but it's nothing that can't be written by anyone else in a short (15-21 days) time. If you want you can read my source code on GitHub... but just remember that it's still alpha material.
The license is Creative Commons SA.
If you want super-lightweight, you could use an auto-prepend file, mixed with some output buffering to build what you want. For starters, you need to set up your prepend and append files - put the following lines in your .htaccess file (you'll probably want to make the prepend and append files unreadable to visitors, too):
php_value auto_prepend_file prepend.php
php_value auto_append_file append.php
Then in your prepend.php file, you'll want to turn on output buffering:
<?php
ob_start();
In append.php, you'll want to grab the contents of the output buffer, clear the buffer and do any other processing of the content you want (in this example, I set a default page title).
<?php
if (!isset($page_title)) {
$page_title = 'Default Page Title';
}
$content = ob_get_contents();
ob_end_clean();
?>
<html>
<head>
<title><?php echo $page_title; ?></title>
</head>
<body>
<?php echo $content ?>
</body>
</html>
After this, you can write each page normally. Here's an example index.php
<?php
$page_title = "Index Page!";
?>
<h1>This is the <?php echo __FILE__; ?> page</h1>
...and an example other.php that does something halfway interesting:
<?php
$page_title = "Secondary Page!";
?>
<h1>This is the <?php echo __FILE__; ?> page</h1>
<p>enjoy some PHP...</p>
<ol>
<?php for ($i = 1; $i <= 10; $i++) : ?>
<li><?php echo "$i $i $i"; ?></li>
<?php endfor ?>
</ol>
And you're done. You can grow on this a bit, such as initializing DB connection in the prepend, but at some point, you'll probably want to move to a more abstract system that breaks out of a fixed mapping of URLs to paths and files.
I'm actually about to release one at europaphp.org along with examples and a full documentation. It's very similar to the Zend Framework in conventions and coding standards. I'll post something when it is done; probably within the next week.
You can get the code at: [http://code.google.com/p/europa/source/browse/#svn/trunk/Sandbox - Default][1].
That link will bring up the latest svn for the Sandbox which you can just download and start using without any configuration.
Currently, it's faster than most any other PHP framework out there.
[1]: http://code.google.com/p/europa/source/browse/#svn/trunk/Sandbox - Default
BareBones: a one-file, no-configuration, MVC framework for PHP5
FryPHP is about as lightweight as it gets.
Limonade might also be useful... not strictly layout.
I've been using Smarty for ages.
It's mature, actively maintained, and widely supported.
Anyway, you'll find a whole range of template engines here:
http://en.wikipedia.org/wiki/Template_engine_(web)
If you click the languages column, you'll easily see what's available for PHP, and how the engines compare.
Just to throw in another framework: CodeIgniter is IMHO very nice, uses an MVC approach, so you'd output your files as views and says to have a small footprint. It also has a template parser on board.
Cheers,