Codeigniter, loading views inside views, variables doesn't reset each time - php

I'm using the latest stable version of Codeigniter.
Here's part of the controller:
$data = array(
'tracks' => $this->tracks_model->get(NULL, 'start_date'),
'longest_distance' => $this->tracks_model->get(10, 'distance'),
'longest_time' => $this->tracks_model->get(10, 'moving_time')
);
$this->load->view('statistics_view', $data);
and here's part of the code inside the file statistics_view.php:
<section>
<h3>Section 1</h3>
<?php $this->load->view('podium_view', array('tracks' => $longest_time, 'unit' => 'ore', 'function' => 'minutes_to_hours')) ?>
</section>
<section>
<h3>Section 2</h3>
<?php $this->load->view('podium_view', array('tracks' => $longest_distance, 'unit' => 'km')) ?>
</section>
I've noticed that in the 2nd loaded view (inside section 2), the variable $function is still set from section 1, and the other values (traks, unit) are the one I passed.
Why the variable function is still set in the second view?
Shouldn't be reset?

In Codeigniter 3 you can also reset variables in view using method
$this->load->clear_vars();
See it in documentation

Codeigniter uses extract in order to convert the array of variables you are passing
see http://php.net/manual/en/function.extract.php
Extract keep adding variable to the symbol table and the view is just included as a PHP file.
So the variable scope is the same and you will have access to all the variables defined early. Default behaviour of extract is it overrides if a conflict is found.
If you want to reset, you will have to pass some value.
<?php $this->load->view('podium_view', array('tracks' => $longest_distance, 'unit' => 'km', 'function'=>'')) ?>

Related

CodeIgniter loading a view into a view

I need to load a view into a view within CodeIgniter, but cant seem to get it to work.
I have a loop. I need to place that loop within multiple views (same data different pages). So I have the loop by itself, as a view, to receive the array from the controller and display the data.
But the issue is the array is not available to the second view, its empty
The second view loads fine, but the array $due_check_data is empty
SO, I've tried many things, but according to the docs I can do something like this:
Controller:
// gather data for view
$view_data = array(
'loop' => $this->load->view('checks/include/due_checks_table', $due_check_data, TRUE),
'check_cats' => $this->check_model->get_check_cats(),
'page_title' => 'Due Checks & Tests'
);
$this->load->view('checks/due_checks',$view_data);
But the array variable $due_check_data is empty
I'm just getting this error, saying the variable is empty?
Message: Undefined variable: due_check_data
You are passing the $view_data array to your view. Then, in your view, you can access only the variables contained in $view_data:
$loop
$check_cats
$page_title
There is no variable due_check_data in the view.
EDIT
The first view is contained in the variable $loop, so you can just print it in the second view (checks/due_checks):
echo $loop;
If you really want to have the $due_check_data array in the second view, why don't you simply pass it?
$view_data = array(
'loop' => $this->load->view('checks/include/due_checks_table', $due_check_data, TRUE),
'check_cats' => $this->check_model->get_check_cats(),
'page_title' => 'Due Checks & Tests',
'due_check_data' => $due_check_data
);
$this->load->view('checks/due_checks',$view_data);
Controller seems has no error. Check out some notices yourself:
<?=$due_check_data?>
This only available in PHP >= 5.4
<? echo $due_check_data; ?>
This only available when you enable short open tag in php.ini file but not recommended
You are missing <?php. Should be something like this
<?php echo $due_check_data; ?>
OK, i managed to solve this by declaring the variables globally, so they are available to all views.
// gather data for view
$view_data = array(
'due_check_data' => $combined_checks,
'check_cats' => $this->check_model->get_check_cats(),
'page_title' => 'Due Checks & Tests'
);
$this->load->vars($view_data);
$this->load->view('checks/due_checks');

PHP variable not returned in array

I am trying to place a variable inside a PHP array which will work with a Wordpress plugin. Here is the code I have:
function custom_list( $lists ) {
$fil = "Dump";
$new_lists = array(
'ddl-list-block' => array(
'name' => __( 'Download Block', 'delightful-downloads' ),
'format' => "
<article class=\"ddl-list-block ddl-list-item\" id=\"ddl-%id%\">
<div class=\"download-wrap\" style=\"background-image: url('fi');\">
<div class=\"download-item\">
<div class=\"download-details\">
<h2>%title%</h2>
".$fil." /* VARIABLE SHOULD APPEAR HERE */
<div class=\"download-meta\">
<div class=\"download-meta-data\"></div>
Download
</div>
</div>
</div>
</div>
</article>
"
),
'ddl-list-plain' => array(
'name' => 'Flain List',
'format' => '<i class="fa fa-download"></i>%title% - %date%'
)
);
return $new_lists;
}
add_filter( 'dedo_get_lists', 'custom_list' );
I have tried using ., {, single quotes and double quotes, but I can not get the word "Dump" to display where it is supposed to. The reason I am trying to get it to show the word "Dump" is just to make sure that variables can be passed through into an array, because I am using another Wordpress plugin (Simple Fields) to manage extra fields in my post types and I want to pull out one particular aspect of the field (the URL of an uploaded image), so I will be inserting something like $my_field['url']. But none of the options I am aware of have even inserted a simple string into my array. Is there something I am missing?
I am posting this solely because it answers my problem. Not necessarily because it answers the question. I guess that's because of the plugin that I used which answers to that function.
The variable I was using called a featured image, but it could not be fed into the function. As a solution, I used their dedo_search_replace_wildcards filter and created another wildcard (I think I used %fi% or something like that), which gave me the outcome I wanted. Shame it didn't feed native $ variables into it.

Yii php: Displaying a widget in a Tab

i've been using Yii framework for some time now, and i've been really having a good time especially with these widgets that makes the development easier. I'm using Yii bootsrap for my extensions..but i'm having a little trouble understanding how each widget works.
My question is how do i display the widget say a TbDetailView inside a tab?
i basically want to display contents in tab forms..however some of them are in table forms...some are in lists, detailviews etc.
I have this widget :
$this->widget('bootstrap.widgets.TbDetailView',array(
'data'=>$model,
'attributes'=>$attributes1,
));
that i want to put inside a tab
$this->widget('bootstrap.widgets.TbWizard', array(
'tabs' => $tabs,
'type' => 'tabs', // 'tabs' or 'pills'
'options' => array(
'onTabShow' => 'js:function(tab, navigation, index) {
var $total = navigation.find("li").length;
var $current = index+1;
var $percent = ($current/$total) * 100;
$("#wizard-bar > .bar").css({width:$percent+"%"});
}',
),
and my $tabs array is declared like this :
$tabs = array('studydetails' =>
array(
'id'=>'f1study-create-studydetails',
'label' => 'Study Details',
'content' =>//what do i put here?),
...
...);
when i store the widget inside a variable like a $table = $this->widget('boots....);
and use the $table variable for the 'content' parameter i get an error message like:
Object of class TbDetailView could not be converted to string
I don't quite seem to understand how this works...i need help..Thanks :)
You can use a renderPartial() directly in your content, like this:
'content'=>$this->renderPartial('_tabpage1', [] ,true),
Now yii will try to render a file called '_tabpage1.php' which should be in the same folder as the view rendering the wizard. You must return what renderPartial generates instead of rendering it directly, thus set the 3rd parameter to true.
The third parameter that the widget() function takes is used to capture output into a variable like you are trying to do.
from the docs:
public mixed widget(string $className, array $properties=array ( ), boolean $captureOutput=false)
$this->widget('class', array(options), true)
Right now you are capturing the object itself in the variable trying to echo out an object. Echo only works for things that can be cast to a string.

Drupal rendering order - how to define order of rendering?

I'm building a site with Drupal and I have a small problem. I'm rendering a form using hook_menu. The form renders fine and all is good. I am then adding some more markup to the page using hook_page_alter(). Hook_page_alter looks like this:
function renderer_page_alter(&$page) {
if(drupal_is_front_page()) {
$q = db_query('SELECT name, mname, number_of_instances FROM {event_type} ORDER BY number_of_instances DESC');
foreach($q as $event) {
$options['name'][] = $event->name;
$options['mname'][] = $event->mname;
}
$tri = array(
'#theme' => 'frontpage_canvas',
'#options' => $options
);
return $page['content']['triangles'] = $tri;
}
}
So in my local MAMP install, the content is displayed with the results from hook_page_alter() first then followed by the form. However, in the remote install, the order is reversed (with the submit button for the form at the top of the page and the rest of the content beneath it). The only difference between the installs (that I can think of) is that the remote install is Drupal 7.8 and the local one is Drupal 7.9.
I would like to have the remote install in the same way as the local one. Has anyone come across an issue like this before?
The basic structure of the rendered HTML is like this:
<div class=content>
//all the form information is in here
</div>
<div class=rendered>
//all the output from hook_page_alter() is here
</div>
EDIT: The issue is that for some reason, block.tpl.php is adding two divs:
<div id="block-system-main" class="block block-system first last odd">
<div class="content">
//My form markup is in here
</div>
</div>
//The hook_page_alter markup is in here.
So, is there any way to force Drupal to add the hook_page_alter markup to the same div as the form is being rendered in? Because the way it's being rendered at the moment, the #weight property doesn't affect the positioning.
Thanks,
The display order in render arrays is set using the #weight attribute, elements with a higher #weight will be rendered after those with a lower value.
If you want to force the content added in hook_page_alter() to be rendered at the top of the content area declare it like this:
$tri = array(
'#theme' => 'frontpage_canvas',
'#options' => $options,
'#weight' => -1000
);
or at the bottom of the content area:
$tri = array(
'#theme' => 'frontpage_canvas',
'#options' => $options,
'#weight' => 1000
);
You can also adjust the #weight for other elements that already exist in the $page array passed in to the function, so you have total control over the display order.

CodeIgniter - How to nest a view in view using second controller

So I have this part in my View:
<body>
<div id = "content">
<?php echo $catalog ?>
</div>
</body>
There are also other variables in it. Here is the part of my Controller where I send them to the View:
$this->load->view('layout',array(
'categories' => $categories,
'home_menu' => $home_menu,
'information' => $information,
'favourite' => $favourite,
'new_products' => $new_products,
'bestsellers' => $bestsellers,
'login_info' => $login_info,
'catalog' => ''
));
I want to create second controller, which when activated sends a second view to the variable $catalog.
Something like this (similar to Kohana):
$this->layout->catalog = $this->load->view('products/catalog', array(
'name' => $name,
'description' => $description));
But it's not working.
My question is, how can I show this second nested view after clicking on a link that activates the second Controller?
EDIT:
But I want to send the catalog view to $catalog variable after the user has clicked on a link that activates second controller, which look something like this:
$products = $this->Product_model->list_products($category_id);
foreach ($products as $row)
{
$name = $row->name;
$description = $row->description;
}
.. after that I want $name and $description to be passed to:
$this->load->view('products/catalog', array(
'name' => $name,
'description' => $description));
..which itself to be passed to $catalog in the layout view defined in the first controller
You can call a $this->load->view within the view's code but I would not recommend it.
Instead pass true as the 3rd parameter in the load view function and this will return the view rather than echo it straight out. Then you can assign that returned code to your original view.
I'm hoping I'm understanding your question fully, but if not, I apologize.
My guess is that you're loading the page with all of the 'extras' and want to be able to update the 'content' part of your page through a user initiated click.
If you're implementing a javascript based solution, then you just need a controller that will output the html fragment and inject that into the current page via an ajax call.
If you're not implementing javascript, then it would be an entire page refresh, so you would just rebuild the page and pass the selected catalog content to the controller.
UPDATE
To do this without ajax or hmvc, you need to get the contents from another controller into this controller, so you could just make an additional request with php:
$catalog_content = file_get_contents('/url_to_second_controller.html');
$this->load->view('layout',array(
'categories' => $categories,
'home_menu' => $home_menu,
'information' => $information,
'favourite' => $favourite,
'new_products' => $new_products,
'bestsellers' => $bestsellers,
'login_info' => $login_info,
'catalog' => $catalog_content
));

Categories