• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Parser libraby doesn't show non-nested variables

#1
Controller function:
PHP Code:
public function test()
 {
 
$data = array('non_nested'   => 'this is non-nested string','blog_entries' => array( array('title' => 'Title 1''body' => 'Body 1'),array('title' => 'Title 2''body' => 'Body 2'),array('title' => 'Title 3''body' => 'Body 3') ) );
 
 $this->parser->parse('test_view',$data);
 } 

Veiew file (test_view.php):
Code:
<html>
<head>
<title>test</title>

</head>
<body>
<div>
{blog_entries}
       <div><span>{title}</span> <span>{body}</span>{non_nested}</div>
{/blog_entries}
</div>

</body>
</html>

Outputs:

Title 1 Body 1{non_nested}
Title 2 Body 2{non_nested}
Title 3 Body 3{non_nested}

Should output:

Title 1 Body 1this is non-nested string
Title 2 Body 2this is non-nested string
Title 3 Body 3this is non-nested string

Tested on CI3.0RC2 - php version 5.5.19, on CI2.0 works fine
Reply

#2
This is a change since CI2 ... see
https://github.com/bcit-ci/CodeIgniter/issues/3394
https://github.com/bcit-ci/CodeIgniter/issues/3189

What you are trying to do is still doable, but differently:
1) embed non-nested parameters inside each nested one too, or
2) do the iteration in your controller, with a view fragment for a single blog entry and then a view fragment similar to the existing one, but with a {content} (or similar) substitution for the accumulated view fragment parses.
Reply

#3
(02-16-2015, 12:23 AM)ciadmin Wrote: This is a change since CI2 ... see
https://github.com/bcit-ci/CodeIgniter/issues/3394
https://github.com/bcit-ci/CodeIgniter/issues/3189

What you are trying to do is still doable, but differently:
1) embed non-nested parameters inside each nested one too, or
2) do the iteration in your controller, with a view fragment for a single blog entry and then a view fragment similar to the existing one, but with a {content} (or similar) substitution for the accumulated view fragment parses.

1. As I'm getting nested data from db by model, it's an additional step and overload to add non-nested var to each array item - if there hundreds of them and they rather long
2. Didn't get this your suggestion, could you please provide an example code

What I figured out is something like this
Code:
<div><span>{title}</span> <span>{body}</span><?=$data['non_nested']?></div>
but this is rather inconsistent and neglect all the use of Parser library

As for me I'm filling up $this->data array with all vars nedded for view file to output and provide it to parser, and then use those variables in view files with curly braces as I need - so there is no php code in view as a concept of MVC says
Reply

#4
Agreed. I've been doing it like you until CI3 too. I avoid PHP code in views like the plague Undecided


Your code refactored for nested view fragments...

Controller
Code:
public function test()
{
$data = array(
  'non_nested'   => 'this is non-nested string',
  'blog_entries' => array(
    array('title' => 'Title 1', 'body' => 'Body 1'),
    array('title' => 'Title 2', 'body' => 'Body 2'),
    array('title' => 'Title 3', 'body' => 'Body 3') ) );
  $temp = '';
  foreach ($data['blog_entries'] as $row)
    $temp .= $this->parser->parse('show_row',$row,true);
  $data['temp'] = $temp;
  $this->parser->parse('test_view',$data);
}


View fragment views/show_row:
Code:
<div><span>{title}</span> <span>{body}</span>{non_nested}</div>

View views/test_view:
Code:
<html>
  <head>
    <title>test</title>
  </head>
  <body>
    <div>
      {temp}
    </div>
  </body>
</html>
Reply

#5
PHP Code:
foreach ($data['blog_entries'] as $row)
    
$temp .= $this->parser->parse('show_row',$row,true); 

Here you send only $row array as variables to the generated view instead $data..
This way you don't send those missing variables.

I can suggest instead making the $data['blog_entries'] make a complete new varaible $blog_entries and loop it to get something as:

PHP Code:
public function test()
{
  
$data = array(
    
'non_nested'   => 'this is non-nested string',
  );
  
$blog_entries => array(
    array(
'title' => 'Title 1''body' => 'Body 1'),
    array(
'title' => 'Title 2''body' => 'Body 2'),
    array(
'title' => 'Title 3''body' => 'Body 3')
  );
  
  
$temp '';
  foreach (
$blog_entries as $row)
    
$temp .= $this->parser->parse('show_row',array_merge($data$row),true);
  
$data['temp'] = $temp;
  
$this->parser->parse('test_view',$data);

Best VPS Hosting : Digital Ocean
Reply

#6
(02-16-2015, 10:49 AM)sv3tli0 Wrote:
PHP Code:
foreach ($data['blog_entries'] as $row)
 
   $temp .= $this->parser->parse('show_row',$row,true); 

Here you send only $row array as variables to the generated view instead $data..
This way you don't send those missing variables.

I can suggest instead making the $data['blog_entries'] make a complete new varaible $blog_entries and loop it to get something as:


PHP Code:
public function test()
{
 
 $data = array(
 
   'non_nested'   => 'this is non-nested string',
 
 );
 
 $blog_entries => array(
 
   array('title' => 'Title 1''body' => 'Body 1'),
 
   array('title' => 'Title 2''body' => 'Body 2'),
 
   array('title' => 'Title 3''body' => 'Body 3')
 
 );
 
 
  $temp 
'';
 
 foreach ($blog_entries as $row)
 
   $temp .= $this->parser->parse('show_row',array_merge($data$row),true);
 
 $data['temp'] = $temp;
 
 $this->parser->parse('test_view',$data);


That would work too. I am purposefully relying on the "non-nested" parameter not being substituted, and trying to keep it as simple as possible Undecided

Your approach would have {non-tested} substituted with each row, mine would have it substituted when the encompassing template is parsed.
Reply

#7
As for me solution you provided looks complicated: adding aditional view file is too much. And I think it would be difficult to make CI popular with such solutions.

My solution:

1) try modifying parser library to support non-nested values along with nested ones inside loop (maybe simply by escaping non-nested ones before output to avoid vulnerability - don't think cutting of functionality because of potential vulnerability to be a good practice)

2) create helper function result_array_extend :

with callback function support (result_array_extend($blog_entries, array('non_nested'=> function($i){return $i%2+1;}))
PHP Code:
function result_array_extend($src_arr,$apnd_arr){
 
    foreach ($src_arr as &$src_item){
 
                $i=0;
 
                foreach ($src_item as &$src_item2){
 
                            foreach($apnd_arr as $key=>$apnd_item){
 
                                      if (is_callable($apnd_item)) { $src_item2[$key]=$apnd_item($i); } else {
 
                                          $src_item2[$key]=$apnd_item;
 
                                       }
 
                                       $i++;
 
                             }
 
               }
 
   
 
   return $src_arr;
 } 

or without callback function support (result_array_extend($blog_entries, $data))
PHP Code:
function result_array_extend($src_arr,$apnd_arr){
 
    foreach ($src_arr as &$src_item){
 
                foreach ($src_item as &$src_item2){
 
                            foreach($apnd_arr as $key=>$apnd_item){
 
                                          $src_item2[$key]=$apnd_item;
 
                             }
 
               }
 
   
 
   return $src_arr;
 } 


then in controller :

PHP Code:
$data = array(
 
   'non_nested'   => 'this is non-nested string',
 
 );
 
 $blog_entries => array(
 
   array('title' => 'Title 1''body' => 'Body 1'),
 
   array('title' => 'Title 2''body' => 'Body 2'),
 
   array('title' => 'Title 3''body' => 'Body 3')
 
 );

$blog_entries  result_array_extend($blog_entries,$data);
$this->parser->parse('test_view',$blog_entries); 

in view file:
Code:
...
<div>
{blog_entries}
      <div><span>{title}</span> <span>{body}</span>{non_nested}</div>
{/blog_entries}
</div>
would output:

Title 1 Body 1this is non-nested string
Title 2 Body 2this is non-nested string
Title 3 Body 3this is non-nested string

or (in case of using callback functiion)

Title 1 Body 11
Title 2 Body 22
Title 3 Body 31

some example from real life :
PHP Code:
$array_result $this->some_model->get(); //get data from db table(s)
$aditional_var $this->uri->segments(3); //get var elswhere rather than db table by means of model

$this->data['result_array'] = result_array_extend($array_result,array('aditional_var'=>$aditional_var));

$this->parser->parse('test_view',$this->data['result_array']); //provide view file with extended data from db table 

then in the view I use to form url

Code:
{result_array}
<a href="/{aditional_var}/{colum1}/{colum2}">{colum3}</a>
{/result_array}

as a result we have out model working with db and returning data from table, our controller forming data to output, view file just outputs provided by controller data and NO PHP code in view
Reply


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2020 MyBB Group.