PHP Vars From Included Bootstrap Not Showing Up in View - php

I have created my own little PHP framework for fun, however, I am having trouble passing variables from bootstrap to the views....
if I put an echo,print_r,var_dump my target variable in the bootstrap, the output is displayed in the browser before the tag... yet the target var in bootstrap.php is not available in the view, it is coming up as "" even though at the top of the page it is being output correctly....
Somethings I noticed from similar questions:
- The target variable is not being over written
- The include target path is correct and the file exists
- The file is only being included one time (include_once is only fired once)
Any ideas are greatly appreciated, I am pulling my hair out over here lol...
Source Code
https://gist.github.com/jeffreyroberts/f330ad4a164adda221aa

If you just want to display your site name, I think you can use a constant like that :
define('SITE_NAME', "Jeff's Site");
And then display it in your index.tpl :
<?php echo SITE_NAME; ?>
Or, you can send your variables to the view by extending a little bit your JLR_Core_Views :
class JLR_Core_Views
{
private $data;
public function loadView($templatePath, $data = array())
{
$this->data = $data;
$templatePath = JLR_ROOT . '/webroot/' . $templateName . '.tpl';
if(file_exists($templatePath)) {
// Yes, I know about the vuln here, this is just an example;
ob_start();
include_once $templatePath;
return ob_get_clean();
}
}
function __get($name)
{
return (isset($this->data[$name]))
? $this->data[$name]
: null;
}
}
Then, you can call your template like that :
$view = new JLR_Core_Views();
$view->loadView("index", array("sitename" => "Jeff's Site"));
And here is your index.tpl :
<?php echo $this->siteName; ?>
Below is another example of what you can do.
First, you create this class in order to store all the variables you want :
<?php
class JLR_Repository {
private static $data = array();
public function set($name, $value) {
self::$data[$name] = $value;
}
public function get($name) {
return (isset(self::$data[$name]))
? self::$data[$name]
: null;
}
}
?>
Then, when you want to store something in it :
JLR_Repository::set("sitename", "Jeff's Site");
And in your index.tpl :
<?php echo JLR_Repository::get("sitename"); ?>

try using the 'global' keyword - http://php.net/manual/en/language.variables.scope.php

Related

Converting array key and values into single variables

I know that you can use extract() to achieve this however my circumstances are as followed:
I am building a very small basic MVC framework for personal projects and I have this in my controller:
public function index(){
$data = [
'title' => 'Welcome'
];
$this->view('pages/index', $data);
}
As you can see this passes the data array into the view and you can echo it like:
echo $data['title'];
But I want to echo it like echo $title; I know that extract() can do this but that means I have to manually put extract($data); at the top of every page which isnt the end of the world but I was just curious if there was a way it could be done automatically? I have tried to use extract by putting it inside the view function but that did not work. I have also tried to use extract by putting it in the header file that is required_once in index.php (thus making the header file a static header thats always required) but neither has worked so any advice would be great.
Here is the code for the view function as requested:
public function view($view, $data = []){
if(file_exists('../../views/'.$view.'.php')){
require_once '../../views/'.$view.'.php';
} else {
die('View does not exist');
}
}
Simple that is it ,use compact and extract function
index method
public function index(){
$title='Welcome';
$this->view('pages/index', compact('title'));
}
Wiew method
public function view($view, $data = []){
extract($data);
if(file_exists('../../views/'.$view.'.php')){
require_once '../../views/'.$view.'.php';
} else {
die('View does not exist');
}
}
In html
<h1> hello <?php echo $title; ?></h1>
Here is where I went wrong, I put extract in the view method before and it didn't work.
However the advice here was to put it in the view function and I now understand that I put the extract function after require_once '../../views/'.$view.'.php'; I just put extract before that line of code and it is now working!

function as function input php

I want to create my own template for building my next web projects.
But my problem is that I am trying to create my own template system with my own function, also to learn more about coding on my on aswell.
I'm trying to improve my code to be me clean/smooth as I code.
But now I ran into this problem
a-function-file.php
<?php
$Website_info = array("SiteTitle"=>"CLiCK", "BaseUrl"=>"http://localhost/CLick/");
//css styles her
$website_styles = array(
array("src"=>"libs/css/bootstrap.min.css", "type"=>"text/css"),
array("src"=>"libs/themes/click.css", "type"=>"text/css")
);
//javascripts her
$website_scripts = array(
array("src"=>"libs/js/bootstrap.min.js", "type"=>"text/javascript")
);
$website_navigation_top_links = array(
array("link"=>"index.php","name"=>"Home")
);
function Click_styles()
{
global $website_styles;
$styleOutput = "";
foreach ($website_styles as $key => $CssStyle):
$styleOutput .= "<link href='".$CssStyle["src"]."' rel='stylesheet' type='".$CssStyle["type"]."'>\n";
endforeach;
return $styleOutput;
}
//my function to create html codes within head tags
function Click_header()
{
//Getting website info into function
global $Website_info;
global $website_styles;
$ImpotedStyles = Click_styles();
//creating the html (can maybe be created more clean later)
$Header_output = "<title>".$Website_info["SiteTitle"]."</title>\n";
$Header_output .= "<base href='".$Website_info["BaseUrl"]."' />\n";
$Header_output = $Header_output.$ImpotedStyles;
// return the complied output (as HTML)
return $Header_output;
}
?>
So far so good, because this works if I write
<?php echo Click_header();?>
But I want to use the function like this with, by passing it a function as an argument
<?php
//the function that doesnt work
function printHTML($ThisShouldBeAFunctionNotAVar, $Description="none") {
echo $ThisShouldBeAFunctionNotAVar
}
?>
<?php
//how I want to use the function
printHTML(Click_header(), "The website header");
//and maybe if I had a footer I could display the return of that function too
printHTML(Click_foter(), "a smart footer function");
?>
I hope you can help me with this or get a better understanding for maybe something smarter
I fount this solution on my own
<?php
function printHTML($CustomFunction,$Description="")
{
$function = ($CustomFunction;
echo $function();
}
?>

Use variables for more than one output? [ PHP Functions ]

I'm currently a beginner developer and have just started my first big project whilst I have spare time, What I'm trying to do is basically write variables to a html/tpl document, Which I have currently got working, Here is my code:
private function index(){
$username = 'MyUsername';
$onlineTime = 'MyOnlineTime';
$this->setParams('Username', $username); // $username Will be replaced by database queried results once completed.
}
And here is the setParams function.
function setParams($item1, $item2){
ob_start();
$theme = 'default';
include_once T . '/'.$theme.'/index.php'; // T . is defined at the beginning of the document.
if ((($html = ob_get_clean()) !== false) && (ob_start() === true))
{
echo preg_replace('~{(['.$item1.']*)}~i', ''.$item2.'', $html, 1);
}
}
And here is the coding inside the html/tpl document.
{username} has been online for {onlineTime} Hours
This is probably a very simple code for some of you but as this is my first attempt this is all I can do.
What I would like to do is have it so you can setParams as many times as you want without changing the $variable names like so:
private function index(){
$username = 'MyUsername';
$onlineTime = 'MyOnlineTime';
$this->setParams('Username',$username);
$this->setParams('OnlineTime', $onlineTime);
}
whilst keeping the setParams($item1, $item2)
But as you can imagine this just cuts the code completely. Does anyone know a solution to this problem? I've been searching all day without any real luck.
Thanks In Advance,
Ralph
I think what you need is a class with a static method;
<?php
class Params {
public static $params = array();
public static function setParam($key, $value) {
self::$params[$key] = $value;
}
public static function getParam($key) {
if (isset(self::$params[$key])) {
return self::$params[$key];
}
}
}
// Usage
// Set Username
Params::setParam("username", "JohnDoe");
Params::setParam("password", "12345");
echo Params::getParam("username");
echo Params::getParam("password");

Creating multilanguage homepage

so im making homepage with three languages.
I am using switch method, here is code -
public function languages()
{
if (isset($_GET['lang']) && $_GET['lang'] != '')
{
$_SESSION['lang'] = $_GET['lang'];
}
else
{
$_SESSION['lang'] = 'en_EN';
}
switch($_SESSION['lang'])
{
case 'en_EN': require_once('language/lang.eng.php');break;
case 'lv_LV': require_once('language/lang.lv.php');break;
case 'ru_RU': require_once('language/lang.ru.php');break;
default: require_once('language/lang.eng.php');
}
}
public function translate($txt)
{
global $text;
return $text[$txt];
}
and it should display in index.php file like this -
<?php $index->translate('search'); ?>
but the problem is that it shows no errors, no notices, no warnings and no translated or default text.
I included function languages() , maybe you can help me with this problem?
EDIT:
im calling $language at start of index.php file - <?php require_once('class.index.php'); $index = new index; $index->languages(); ?> and $text is defined in lang.eng.php; lang.lv.php and lang.ru.php file.
Since you're using a class, I think it's better to use properties instead of globals, it will be easier in future mantainance. Create a class variable holding $text and use that
class Index {
var $text;
public function languages()
{
require(".....");
$this->text = $text;
}
public function translate($txt)
{
if(isset($this->text[$txt]))
{
return $this->text[$txt];
}
else
{
return "no translation";
}
}
}
$index = new Index;
$index->languages();
echo $index->translate('search');
type
<?php echo $index->translate('search'); ?>
Check first whether the session is initialized or not and also place the languages() function call before the translate so that it loads the language prior to translation and also put error_reporting(E_ALL) at top so that any error suppresion will be be removed and also put echo the returned result of translate statement

Simple template var replacement, but with a twist

So I'm setting up a system that has a lot of emails, and variable replacement within it, so I'm writing a class to manage some variable replacement for templates stored in the database.
Here's a brief example:
// template is stored in db, so that's how this would get loaded in
$template = "Hello, %customer_name%, thank you for contacting %website_name%";
// The array of replacements is built manually and passed to the class
// with actual values being called from db
$replacements = array('%customer_name%'=>'Bob', '%website_name%'=>'Acme');
$rendered = str_replace(array_keys($replacements), $replacements, $template);
Now, that works well and good for single var replacements, basic stuff. However, there are some places where there should be a for loop, and I'm lost how to implement it.
The idea is there'd be a template like this:
"hello, %customer_name%, thank you for
requesting information on {products}"
Where, {products} would be an array passed to the template, which the is looped over for products requested, with a format like:
Our product %product_name% has a cost
of %product_price%. Learn more at
%product_url%.
So an example rendered version of this would be:
"hello, bob, thank you for requesting
information on:
Our product WidgetA has a cost of $1.
Learn more at example/A
Our product WidgetB has a cost of $2.
Learn more at example/B
Our product WidgetC has a cost of $3.
Learn more at example/C.
What's the best way to accomplish this?
Well, I really dont see the point in a template engine that uses repalcements/regex
PHP Is already a template engine, when you write <?php echo $var?> its just like doing <{$var}> or {$var}
Think of it this way, PHP Already translates <?php echo '<b>hello</b>'?> into <b>hello</b> by its engine, so why make it do everything 2 times over.
The way i would implement a template engine is like so
Firstly create a template class
class Template
{
var $vars = array();
function __set($key,$val)
{
$this->vars[$key] = $val;
}
function __get($key)
{
return isset($this->vars[$key]) ? $this->vars[$key] : false;
}
function output($tpl = false)
{
if($tpl === false)
{
die('No template file selected in Template::output(...)');
}
if(!file_exists(($dir = 'templates/' . $tpl . '.php')))
{
die(sprintf('Tpl file does not exists (%s)',$dir));
}
new TemplateLoader($dir,$this->vars);
return true;
}
}
This is what you use in your login such as index.php, you will set data just like an stdClass just google it if your unsure. and when you run the output command it sends the data and tpl to the next class below.
And then create a standalone class to compile the tpl file within.
class TemplateLoader
{
private $vars = array();
private $_vars = array(); //hold vars set within the tpl file
function __construct($file,$variables)
{
$this->vars = $variables;
//Start the capture;
ob_start();
include $file;
$contents = ob_get_contents();
ob_end_clean(); //Clean it
//Return here if you wish
echo $contents;
}
function __get($key)
{
return isset($this->vars[$key]) ? $this->vars[$key] : (isset($this->_vars[$key]) ? $this->_vars[$key] : false) : false;
}
function __set($key,$val)
{
$this->_vars[$key] = $val;
return true;
}
function bold($key)
{
return '<strong>' . $this->$key . '</string>';
}
}
The reason we keep this seperate is so it has its own space to run in, you just load your tpl file as an include in your constructor so it only can be loaded once, then when the file is included it has access to all the data and methods within TemplateLoader.
Index.php
<?php
require_once 'includes/Template.php';
require_once 'includes/TemplateLoader.php';
$Template = new Template();
$Template->foo = 'somestring';
$Template->bar = array('some' => 'array');
$Template->zed = new stdClass(); // Showing Objects
$Template->output('index'); // loads templates/index.php
?>
Now here we dont really want to mix html with this page because by seperating the php and the view / templates you making sure all your php has completed because when you send html or use html it stops certain aspects of your script from running.
templates/index.php
header
<h1><?php $this->foo;?></h1>
<ul>
<?php foreach($this->bar as $this->_foo):?>
<li><?php echo $this->_foo; ?></li>
<?php endforeach; ?>
</ul>
<p>Testing Objects</p>
<?php $this->sidebar = $this->foo->show_sidebar ? $this->foo->show_sidebar : false;?>
<?php if($this->sidebar):?>
Showing my sidebar.
<?php endif;?>
footer
Now here we can see that were mixing html with php but this is ok because in ehre you should only use basic stuff such as Foreach,For etc. and Variables.
NOTE: IN the TemplateLoader Class you can add a function like..
function bold($key)
{
return '<strong>' . $this->$key . '</string>';
}
This will allow you to increase your actions in your templates so bold,italic,atuoloop,css_secure,stripslashs..
You still have all the normal tools such as stripslashes/htmlentites etc.
Heres a small example of the bold.
$this->bold('foo'); //Returns <strong>somestring</string>
You can add lots of tools into the TempalteLoader class such as inc() to load other tpl files, you can develop a helper system so you can go $this->helpers->jquery->googleSource
If you have any more questions feel free to ask me.
----------
An example of storing in your database.
<?php
if(false != ($data = mysql_query('SELECT * FROM tpl_catch where item_name = \'index\' AND item_save_time > '.time() - 3600 .' LIMIT 1 ORDER BY item_save_time DESC')))
{
if(myslq_num_rows($data) > 0)
{
$row = mysql_fetch_assc($data);
die($row[0]['item_content']);
}else
{
//Compile it with the sample code in first section (index.php)
//Followed by inserting it into the database
then print out the content.
}
}
?>
If you wish to store your tpl files including PHP then that's not a problem, within Template where you passing in the tpl file name just search db instead of the filesystem
$products = array('...');
function parse_products($matches)
{
global $products;
$str = '';
foreach($products as $product) {
$str .= str_replace('%product_name%', $product, $matches[1]); // $matches[1] is whatever is between {products} and {/products}
}
return $str;
}
$str = preg_replace_callback('#\{products}(.*)\{/products}#s', 'parse_products', $str);
The idea is to find string between {products} and {products}, pass it to some function, do whatever you need to do with it, iterating over $products array.
Whatever the function returns replaces whole "{products}[anything here]{/products}".
The input string would look like that:
Requested products: {products}%product_name%{/products}

Categories