PHP template/layout function - php

I have this function but it's not good. It's making it hard to debug my code:
fun... {
eval('?>' . str_replace(
'{yield}',
file_get_contents('templates/' . $template . '.phtml'),
file_get_contents('templates/layouts/' . $layout . '.phtml')
));
}
Please let me know of better replacements.
Thanks.

function render($template, $layout) {
$cache = "wherever/you/put/the/cache/file/{$template}_{$layout}.phtml";
if (!file_exists($cache)) {
$template = file_get_contents('templates/' . $template. '.phtml');
$layout = file_get_contents('templates/layouts/' . $layout . '.phtml');
$output = str_replace('{yield}', $template , $layout);
file_put_contents($cache, $output);
} else {
include($cache);
}
}

using output buffering is the best way for acheiving a filled template data
ob_start();
include "my/template/link.phtml";
$content = ob_get_contents();
ob_end_clean();

Related

html being processed in string_replace as variable

I have a html <h1 class="title">[VALUE]</h1> where [VALUE] gets replaced with some data when the template is processed.
I would like to used the data that replaces [VALUE] in a php variable.
Something like this,
$my_var = '[VALUE]';
but the above don't work.
function getHTML($articleid, $fieldid, $category = false, $write=false)
{
global $globalreturn;
//$str = fieldattach::getInput($articleid, $fieldid, $category);
$html ='';
$valor = fieldattach::getValue( $articleid, $fieldid , $category );
$title = fieldattach::getName( $articleid, $fieldid , $category );
$published = plgfieldsattachment_input::getPublished( $fieldid );
if(!empty($valor) && $published)
{
$html = plgfieldsattachment_input::getTemplate($fieldid);
if(fieldattach::getShowTitle( $fieldid )) $html = str_replace("[TITLE]", $title, $html);
else
$html = str_replace("[TITLE]", "", $html);
$html = str_replace("[VALUE]", $valor, $html);
$html = str_replace("[FIELD_ID]", $fieldid, $html);
}
//WRITE THE RESULT
if($write)
{
echo $html;
}else{
$globalreturn = $html;
return $html;
}
}
function getTemplate($fieldsids, $file="input", $valor)
{
global $globalreturn;
echo $valor;
$templateDir = dirname(__FILE__).'/tmpl/'.$file.'.tpl.php';
$html = file_get_contents ($templateDir);
$app = JFactory::getApplication();
$templateDir = JPATH_BASE . '/templates/' . $app->getTemplate().'/html/com_fieldsattach/fields/'.$file.'.tpl.php';
if(file_exists($templateDir))
{
$html = file_get_contents ($templateDir);
}
$app = JFactory::getApplication();
$templateDir = JPATH_BASE . '/templates/' . $app->getTemplate().'/html/com_fieldsattach/fields/'.$fieldsids.'_'.$file.'.tpl.php';
if(file_exists($templateDir))
{
include ($templateDir);
}
//return $html;
}
I am trying to use the $valor form function getHTML(); inside the getTemplate();
As you will see in he code above I already tried to call global $globalreturn and then echo $valor; but it doesn't work.
You can try as follows
I think you want pass variable to another page. So add following code in myfile.php
<h1 class="title"><?php define ( 'myVariable', '[VALUE]' ); ?></h1>
And call using require function in your next page.
<?php
require("myfile.php");
?>

how to limit numwords article in codeigniter?

i have cms blog with codeigniter. but when i limit content in article is not working. i am newbie in codeigntier can you tell me what am i to do.
this is cms_helper.php
function get_excerpt($article, $numwords = 20){
$string = '';
$url = article_link($article);
$string .= '<h2>' . anchor($url, e($article->judul_berita)) . '</h2>';
$string .= '<p class="pubdate">' . e($article->tanggal) . '</p>';
$string .= '<p>' . e(limit_to_numwords(strip_tags($article->content), $numwords)) . '</p>';// content is not show
$string .= '<p>' . anchor($url, 'Read more', array('judul_berita' => e($article->judul_berita))) . '</p>';
return $string;
}
function limit_to_numwords($string, $numwords){
$excerpt = explode(' ', $string, $numwords + 1);
if (count($excerpt) >= $numwords) {
array_pop($excerpt);
}
$excerpt = implode(' ', $excerpt);
return $excerpt;
}
function e($string){
return htmlentities($string);
}
in controller
private function _homepage()
{
$this->load->model('mberita');
$this->db->limit(6);
$this->data['articles'] = $this->mberita->get_berita();
//var_dump($this->data['articles']);
}
please help me what to do. thank you.
You should use Codeigniter text helper:
$this->load->helper('text'); // add this to the the function or to the constructor
$string .= '<p>' . e(word_limiter(strip_tags($article->content), $numwords)) . '</p>';
In this article you can find many useful codeigniter text functions
Try the below sample. this will surely work.
function limit_to_numwords($text,$no_words){
$next=substr($text,$no_words,strlen($text));
$spacepos=strpos($next," ");
$desc=substr($text,0,$no_words+$spacepos)."...";
return $desc;
}
From this, you can get exact full word text from the nearest space character. hope this will help your requirement.
Also, try to call the function as "$this->limit_to_numwords"

Convert Variable to global in the class . . .php?

I need to send $user to inside the class and render function to make it global variable.
because it not work unless i write "$user" in the class and render function.
Please help me.
$user = 'admin';
class Template{
public function render($template_name)
{
global $user;
$path = $template_name . '.html';
if (file_exists($path))
{
$contents = file_get_contents($path);
function if_condition($matches)
{
$parts = explode(" ", $matches[0]);
$parts[0] = '<?PHP if(';
$parts[1] = '$' .$parts[1]; // $page
$parts[2] = ' ' . '==' . ' ';
$parts[3] = '"' . substr($parts[3], 0, -1) . '"'; //home
$allparts = $parts[0].$parts[1].$parts[2].$parts[3].') { ?>';
return $allparts.$gvar;
}
$contents = preg_replace_callback("/\[if (.*?)\]/", "if_condition", $contents);
$contents = preg_replace("/\[endif\]/", "<?PHP } ?>", $contents);
eval(' ?>' . $contents . '<?PHP ');
}
}
}
$template = new Template;
$template->render('test3');
Never, never use global variables
They are awful, they bind your code to context and they are side-effect - if you'll change your variable somewhere in 2054-th line of 119-th included file, the behavior of your application will change and then good luck with debugging that.
Instead you should either pass your user in method's parameters:
public function render($template_name, $user)
or create property in class instance:
class Template
{
protected $user = null;
public function render($template_name)
{
//access to $this->user instead of $user
}
//...
}
-and, of course, initialize $user property in class constructor.

How do I access a variable inside of preg_replace_callback?

I'm trying to replace {{key}} items in my $text with values from a passed array. but when I tried adding the print_r to see what was going on I got a Undefined variable: kvPairs error. How can I access my variable form within the preg_replace_callback?
public function replaceValues($kvPairs, $text) {
$text = preg_replace_callback(
'/(\{{)(.*?)(\}})/',
function ($match) {
$attr = trim($match[2]);
print_r($kvPairs[strtolower($attr)]);
if (isset($kvPairs[strtolower($attr)])) {
return "<span class='attr'>" . $kvPairs[strtolower($attr)] . "</span>";
} else {
return "<span class='attrUnknown'>" . $attr . "</span>";
}
},
$text
);
return $text;
}
Update:
I've tried the global scope thing, but it doesn't work either. I've added 2 print statements to see whats doing on, one inside and one outside the preg_replace_callback.
public function replaceValues($kvPairs, $text) {
$attrTest = 'date';
print_r("--" . strtolower($attrTest) . "--" . $kvPairs[strtolower($attrTest)] . "--\n");
$text = preg_replace_callback(
'/(\{{)(.*?)(\}})/',
function ($match) {
global $kvPairs;
$attr = trim($match[2]);
print_r("==" . strtolower($attr) . "==" . $kvPairs[strtolower($attr)] . "==\n");
if (isset($kvPairs[strtolower($attr)])) {
return "<span class='attr'>" . $kvPairs[strtolower($attr)] . "</span>";
} else {
return "<span class='attrUnknown'>" . $attr . "</span>";
}
},
$text
);
return $text;
}
The output I get is:
--date--1977-05-20--
==date====
As your callback function is a closure, you can pass extra arguments via use
function ($match) use ($kvPairs) {
...
}
better than polluting the global space

Simple templating with str_replace

I'm just experimenting first of all.
I just came up with an idea of making my own in a simple way here:
class Template
{
function parse($template_file, $braces)
{
if(file_exists($template_file))
{
$template = file_get_contents($template_file);
foreach($braces as $brace => $replacement)
{
$brace = trim(strtoupper($brace));
$build = str_replace('{' . $brace . '}', $replacement, $template);
}
echo $build;
}
else
{
trigger_error('Template file does not exist: ' . $template_file, E_ERROR);
}
}
}
This in order to work:
$template = new Template();
$template->parse('index_body.html', array('ONE' => 'one',
'TWO' => 'two',
'THREE' => 'three'));
index_body.html:
{ONE}
{TWO}
{THREE}
The problem is, that it only outputs:
{ONE} {TWO} three
It always replaces the last brace, how come not the whole array?
$build = str_replace('{' . $brace . '}', $replacement, $template);
^^^^^^^^^
You're always replacing against the original template, never against the updated one. Either keep assigning $template, or update $build
$template = file_get_contents($template_file);
$build = $template;
foreach($braces as $brace => $replacement)
{
$brace = trim(strtoupper($brace));
$build = str_replace('{' . $brace . '}', $replacement, $build);
}
It only replaces the last place because in each case, you're replacing the value in the original $template variable. It's not updating the variable each iteration.
You echo $build, which is being reassigned every foreach iteration.
You should've written this instead
$template = str_replace('{' . $brace . '}', $replacement, $template);
How about using like full php engine power (similar to smarty interface):
just for experimenting:
class Template {
private $_file;
private $_variables = array();
public function __construct($file = null) {
$this->_file = $file;
}
public function set($key, $value) {
$this->_variables[$key] = $value;
}
public function fetch($file = null) {
if (!$file) {
$file = $this->_file;
}
extract($this->_variables);
ob_start();
require($file);
$content = ob_get_contents();
ob_end_clean();
return $content;
}
public function display($file = null) {
if (!$file) {
$file = $this->_file;
}
$result = $this->fetch($file);
echo $result;
}
}
=============
$tpl = new Template('hello.tpl');
$tpl->set('world', 'earth');
$tpl->display();
=============
Template sample:hello.tpl
Hello <?=$world;?>
Your $build is overwritten in each iteration. This will solve the issue.
class Template
{
function parse($template_file, $braces)
{
if(file_exists($template_file))
{
$template = file_get_contents($template_file);
foreach($braces as $brace => $replacement)
{
$brace = trim(strtoupper($brace));
$temp = str_replace('{' . $brace . '}', $replacement, $template);//create a temporary array
$build = array_merge($build ,$temp);
}
echo $build;
}
else
{
trigger_error('Template file does not exist: ' . $template_file, E_ERROR);
}
}
}

Categories