I've a function inside a view (I've nested code so there is no alternative).
My problem is made because i want to add some vars inside the function.
I can't access to the var inside the function.
<div>
<?php _list($data); ?>
</div>
<?php
echo $pre; // Perfect, it works
function _list($data) {
global $pre;
foreach ($data as $row) {
echo $pre." ".$row['title']; // output ' title' without $pre var
if (isset($row['childrens']) && is_array($row['childrens'])) _list($row['childrens']);
}
}
?>
Simple... just define the function like this:
function _list($data, $pre=NULL)
then inside the function, you could check if the $pre is NULL then search for it somewhere else... using the global statement in functions is not desirable.
On the other hand you can define('pre',$pre); and use the pre constant created in your function... again not desirable but it would work for your example.
Later edit: DEFINE YOUR FUNCTIONS IN HELPERS
i am not sure why i forgot to suggest that in the first place
define function in view is weird. using global variable make it worse.
maybe you should avoid the global function with this:
<div>
<?php
foreach($data as $row){
_list($pre, $row);
}
?>
</div>
<?php
function _list($pre, $row) {
echo $pre." ".$row['title'];
if (isset($row['childrens']) && is_array($row['childrens'])){
foreach($row['childrens'] as $child){
_list($pre, $child);
}
}
}
?>
btw, define function in helpers would be better
http://ellislab.com/codeigniter/user-guide/general/helpers.html
whsh they help
Related
I’m creating a plugin called woomps. In the main php file i do a calculation when template redirect.
add_action('template_redirect','woomps_loop');
This calculates x: (it’s actually a big calculation).
function woomps_loop() {
$x = 10;
Return $x
}
I want to show this variable based on a shortcode. Therefore, in my main php file I include the frontend.php through this code.
function woomps_scripts() {
include 'frontend.php';
}
add_action('wp_enqueue_scripts','woomps_scripts');
Where the frontend.php has this code
function woomps_subscription_slider (){
//How do I call the variable from woomps_loop() without running all the code again.
echo "<div>\n";
echo "<p>\n";
echo $x;
echo "</p>\n";
echo "</div>\n";
}
add_shortcode("woomps-subscription-slider", "woomps_subscription_slider");
The shortcode is added to one of my pages so it displays, but……
How do I call the $x variable form woomps_loop() without running the code again?
This <div> will come before all other content generated in the_content(). Why is that?
global $x; //Had to define it global before setting it, i dident understand this before #cameronjonesweb exmample.
$x = $total_qty;
Then reference it like this:
function woomps_subscription_slider ($x){
global $x_subs;
$content = <<<EOD
<div>
<p>
{$x_subs}
</p>
</div>
EOD;
return $content;
} //end woomps_subscription_slider
It worked. Try this EOD to return multiple lines of HTML, and it does get placed inside the_content() loop
Okay. Thank you!
1) Store it as a global variable. So change your woomps_loop function to
global $x;
function woomps_loop() {
global $x;
$x = 10;
return $x
}
(PS you probably won't need to return $x here now)
Then also define $x in your shortcode function
function woomps_subscription_slider (){
global $x;
echo "<div>\n";
//... rest of it carries on
2) Because you're echoing. Return the value instead.
I want to use a variable inside an HTML-String of another PHP-File template.php in my PHP-File constructor.php.
I´m searched on Stackoverflow for a workaround to include the content of the other PHP-File. I included the following code into constructor.php because its known to be more safe instead of using file_get_contents(); Source:
function requireToVar($file){
ob_start();
require($file);
return ob_get_clean();
}
The rest of constructor.php looks like this:
...
$sqli = mysqli_query($mysqli, "SELECT ...");
if(mysqli_num_rows($sqli) > 0){
$ii = 0;
while ($row = $sqli->fetch_assoc()) {
$ii++;
if($row['dummy']=="Example"){
$content.=requireToVar('template.php');
...
The template.php looks like this:
<?php echo "
<div class='image-wrapper' id='dt-".$row['id']."' style='display: none;'>
...
</div>
"; ?>
The constructor.php doesn´t recognize the var $row['id'] inside the string of template.php as its own variable and also doesn´t execute it. The variable definitely works for the other code in constructor.php.
If I´m copy&paste the code of template.php into constructor.php after $content.= its working like a charm. But I want to restructure my constructor.php because its getting to big and this way its easier to customize.
I don´t know how to describe this problem more exactly, but I´m hoping this title fits to my problem.
Update your function
function requireToVar($file,$row_id){
ob_start();
require($file);
return ob_get_clean();
}
so you can call it like that
while ($row = $sqli->fetch_assoc()) {
$ii++;
if($row['dummy']=="Example"){
$content.=requireToVar('template.php',$row['id']);
and display it in template.php like that
<div class="image-wrapper" id="dt-<?php echo $row_id; ?>" style="display: none;"></div>
Use MVC model and renderer functions. For example: index.php
<!DOCTYPE HTML>
<html>
<head>
<title><?=$title; ?></title>
</head>
<body>
<h3><?=$text; ?></h3>
</body>
</html>
Than I'll have PHP array that contains those variables:
$array = array("title"=>"Mypage", "text"=>"Mytext");
Now we will use both in renderer function
function renderer($path, $array)
{
extract($array); // extract function turn keys into variables
include_once("$path.php");
}
renderer("index", $array);
Your approach is rather strange, but anyway; you can access $row from within $GLOBALS array.
Write your template as:
<?php echo "
<div class='image-wrapper' id='dt-".$GLOBALS['row']['id']."' style='display: none;'>
...
</div>
";
?>
Where should we process mysql queries in CodeIgniter application?
For example in a simple project we do like this :
for controller:
class Blog extends CI_Controller {
function posts(){
$data['query'] = $this->blog_model->index_posts();
$this->load->view('blog_view', $data);
}
}
and in view :
<?php
while ($post = mysql_fetch_object($query)):
?>
<div>
<p><?= $post->body; ?></p>
</div>
<?php endwhile; ?>
But, if we want to do something with body of post before print where should it be done?
For example, I want to write a function that formats the body of post and pass the body to it before doing echo.
Where should it be placed according to CoeIgniter's structure and recommended practices? (best option)
in the controller? (if so , how to use it)
in the view?
write a helper?
other approaches ?
Here's what is recommended:
Controller:
function posts() {
$this->load->model("blog_model");
$data['rows'] = $this->blog_model->index_posts();
$this->load->view("blog_view", $data);
}
Model: (blog_model.php)
function index_posts() {
$this->load->database();
$query = $this->db->get('your_table');
$return = array();
foreach ($query->result_array() as $line) {
$line['body'] = ... do something with the body....
$return[] = $line;
}
return $return;
}
View: (blog_view.php)
<?php foreach ($rows as $line): ?>
<div>
<p><?php echo $line['column']; ?></p>
</div>
<?php endforeach; ?>
Basically what happens is your model returns a multidimensional array that is passed the view and processed using a foreach() loop.
Good luck!
If you want to reuse that function create a helper. If you want this function only once put it in your controller and call from that controller.
Models are just for accessing database or maybe in few other cases, but mostly just for accessing things in database or editing, deleting etc. and sending the result to controller for further processing.
In your case I would stick with helper.
E.g. you will create a file top_mega_best_functions.php and put it inside helpers folder.
Than you write ther e.g. something like
function red_text($input) {
echo '<span style="color: red;">';
echo $input;
echo '</span>';
}
Then load the helper in your autoloader file or load before using.
And use in your view or controller like
$blablabla = "This text will be red";
red_text($blablabla);
This is really basic PHP. Can someone tell me why this does not work and what I need to do to make it work.
<?php
$test_var=12;
proc_scrn($test_var);
proc_scrn($local_pid)
{
echo "tp12",$local_pid ;
}
?>
Well, you haven't actually created a function there. This would work:
<?php
$test_var=12;
proc_scrn($test_var);
function proc_scrn($local_pid='')
{
echo "tp12: ".$local_pid;
}
?>
function proc_scrn($local_pid)
{
// something
}
PHP- User-defined functions
Pretty simple
<?php
$var=1;
function proc_scrn($var1){
echo "tp12: ".$var1;
}
proc_scrn($var);
?>
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}