CI: Use view/controller in another included view? - codeigniter

I'm new to CI & PHP.
I have an auth library included, and works great stand-alone.
I simply want to have the login form load as a view inside another view...is that weird?:
I'm quasi-templating:
index:
$this->load->view('head_content');
$this->load->view('stuff');
$this->load->view('footer');
Inside the stuff view:
<stuff></>
$this->load->view('login_view');
<morestuff></>
I just want the login form to show up on the front page, and then tie into the auth system...

You have to load the login view in the controller, and then pass the data to the stuff view.
In the controller:
$this->load->view('head_content');
// the line below will save the output of the login view to $data['login']
// instead of outputting to the screen
$data['login'] = $this->load->view('login_view', '', TRUE);
$this->load->view('stuff');
$this->load->view('footer');
In the stuff view:
<stuff>
<?php echo $login; ?>
<morestuff>

In the page Views, at the bottom, check out the section Returning views as data

I've just recommended this but I'm going to recommend it again:
http://codeigniter.com/forums/viewthread/77279/
Django-like template inheritance helper for CodeIgniter.
I use this on ALL of my CI projects and it makes things like this stupidly easy.

Related

Laravel - Get HTML of current page or of a view according to a path

I have a view mypage.blade.php and a route.
The url is like : https://example.com/mypage/param1/param2. The route use param1 and param2 and generate the page.
Question 1
In that page, I try to get its HTML code. Is there a way to do it?. I tried render() but I don't get what I want.
Question 2
In the view, can I get the HTML code of an other view by specifying a path ?
You had the right idea. Not sure why it wouldn't work for you.
In the controller, set the view into a variable:
$view = view('myBaseView', compact('people', 'places', 'things'));
Now, if you dump the rendered view variable, you have the page's HTML:
dd($view->render());
To get the html of another view by specifying the path and using the internal controller, you would need to set up some kind of a wrapper or catch so that the view variable is not returned as a view, but rendered out to html as above. Your method would need to trap whatever the original controller was sending before it pushed out the view.
Of course, old school php can get the other page's rendered html too possibly if your server is set to allow this:
$html = file_get_contents('http://mypage.com/');
Something else you might find handy is the Laravel sections method. If you just want to render part of the page you can do so by calling whatever section you want from a partial view:
$sections = $view->renderSections(); // returns an associative array of 'content', 'pageHeading' etc
dd($sections['modalContent']); // this will only dump whats in the content section
I don't know what you want to do with this html, but if you wish to display it on a page, once you send it (you'd possibly want to return the view along with a compact of the variable $view... as a normal variable if so), remember to use this format:
{!! $view !!}
HTH

Laravel Redirect as POST

Currently my users must get the visit form given by Route::get then fill it in to get back a result view given by Route::post. I need to create a shareable link such as /account/search/vrm/{vrm} where {vrm} is the VRM that is usually filled in on the form page. This VRM then needs to redirected to Route::post as post data. This needs to be done by my controller. How can I do this in my controller?
Routes:
// Shows form view
Route::get('/account/search', 'User\AccountController#getSearch')->name('account.search');
// Shows result view
Route::post('/account/search', 'User\AccountController#runSearch');
// Redirect to /account/search as POST
Route::get('/account/search/vrm/{vrm}', function($vrm) { ???????? });
POSTs cannot be redirected.
Your best bet is to have them land on a page that contains a form with <input type="hidden"> fields and some JavaScript that immediately re-submits it to the desired destination.
You can redirect to a controller action or call the controller directly, see the answer here:
In summary, setting the request method in the controller, or calling a controller's action.
Ps: I don't want to repeat the same thing.
For those who comes later:
If you are using blade templating engine for the views, you can add '#csrf' blade directive after the form starting tag to prevent this. This is done by laravel to prevent cross site reference attacks. By adding this directive, you can get around this.
return redirect()->route('YOUR_ROUTE',['PARAM'=>'VARIABLE'])

Joomla display view not displaying site template

I am trying to load a view from my controller using the follow code but I only get a raw HTML view and does not show the site's template.
$view = $this->getView( 'download', 'html' );
$view->display();
Can some help me in what I am doing wrong to display the site's template.
I also tried a redirect but that did not work either
$this->redirect(JRoute::_('index.php?option=com_atdwcsv&view=download'), false);
Edit: I figured out what was wrong with the redirect. Code I needed was
$this->setRedirect('index.php?option=com_atdwcsv&view=download');
$this->redirect();
I could be wrong, but I don't think you need to use the display() method on the view, I think you need to use $this->display(); instead.

codeigniter - loading a library from a view?

I have some data that I have to display as a table.
I think I should pass the data from the controller as $data['events'] = array(.....
and then load the view to display them.
<?php
$this->load->library('table');
echo $this->table->generate($events);
?>
this doesn't work though - it gives a Fatal error: Call to a member function generate() on a non-object
If I paste the same code in the controller, obviously using ->generate($data['events'] the table gets displayed correctly.
Should I get that views can't load libraries, or I am doing something wrong?
Or maybe should I capture the output of the library in the controller and send that to the view?
If you need to call a library (and its functions) within a view, you can do this:
$CI =& get_instance();
$CI->load->library('library_name');
$CI->library_name->yourFunction();
You should run below code in the controller:
<?php
$this->load->library('table');
echo $this->table->generate($events);
?>
and store the data in variable and then send to the view.
To answer what you are doing wrong, you should know that the CodeIgniter class isn't declared in the view, and that this is the case for a reason - to abstract your PHP code from your HTML. Views should contain minimal PHP code (basic loops, conditions).
With this in mind, you should include your library as normal in the controller as follows;
controller
$this->load->library('table');
$data['events_table'] = $this->table->generate($events);
$this->load->view(....);
In the view, you simple echo the data. Although CodeIgniter allows short-hand tags, you should use standard PHP tags to keep to a convention that will work anywhere you keep your code.
view
<?php echo $events_table; ?>
You can auto-load the library in config/autoload.php
$autoload['libraries'] = array('database','session','table');
Then you can simply call the functions in your view .
echo $this->table->generate($events);
This was useful for me when i was creating a dynamic menu header . i auto-loaded the library which has the function for dynamic menu creation and then i simply called that function from the view , by the way it is bad practice .
That is one wrong approach to MVC. You don't need to load the library in the view, because all views are loaded from one CONTROLLER, so every external Helper or Library should be loaded from the controller and the used or send to the views
Regards,
Pedro
Note the shoulds: CodeIgniter is flexible in that it lets you do things the wrong way. It just makes it a little more difficult. You can do almost everything in the view, even when you shouldn't; but loading helpers, models, and views has to be done in the controller.
In controller or model use
$this->load->library('mylib');
$mylib=$this->mylib;
$data['mylib']=$mylib;
$this->load->view('myview',$data,false);
and than in view you can use library directly:
$mylib->myfunction();
It's not MVC like solution but works if you need.
Simply load library on controller, then use it view.
Controller:
$this->load->library('table');
$data = array(
array(1,2,3,4,5),
array(1,2,3,4,5),
array(1,2,3,4,5),
);
$this->load->view('the_view', compact('data'));
View:
echo $this->table->generate($data);

What is the best practice for displaying multiple views in Codeigniter?

I'm trying to determine the best practice for calling multiple views from the same method in a controller.
Is it preferable in the controller to make one view call, then have that view call all the views it needs, or call all the views you need in sequence in the controller?
Example:
function index(){
//set all data variables
//then send them to the view
$this->load->view($index_view, $data);
}
or
function index(){
//set variables
//then call each view
$this->load->view($header_view, $header_data);
$this->load->view($body_view, $body_data);
$this->load->view($footer_view, $footer_data);
The Codeigniter guide shows both ways, but does not seem to advise to the best practice...is there one?
I didn't like the way of including the header/footer within the view, and I didn't like loading the footer and header each time in every single Controller function.
To fix this, I extended the Controller class with my own view display function.
<?php
// in application/libraries/MY_Controller.php
class MY_Controller extends Controller {
function _displayPage($page, $data = array()) {
$this->view->load('header', $data);
$this->view->load($page, $data);
$this->view->load('footer', $data);
}
}
?>
// in application/controllers/home.php
<?php
class Home extends MY_Controller {
function index() {
$this->_displayPage('home/index', array('title' => 'Home'));
}
}
?>
Not sure if this is CodeIgniter "best practice" but it makes sense to me.
I don't think there is a definitive answer for that. Choose one and stick with it, it's important to be consistent.
Anyway, I'd prefer the second one.
I would say that the controller should only display one view. Then it's up to the view if it wants to show a header, footer, sidebar or whatever. The controller shouldn't have to care, its job is to get data from a model and hand it to a view. Not decide if the view should have a header and a footer.
Agree with Christian Davén: its view / display logic not data or business / logic. essentially its the same as using php includes for snippets like navigation, footer etc. you're just embedding markup.
This is expected behavior. Once variables are set they become available within the controller class and its view files. Sending an array in $this->load->view() is the same as sending an array directly to $this->load->vars() before calling the view file. This simplifies things for most people using multiple views in a controller. If you are using multiple view files in a single controller and want them to each have their own set of variables exclusively, you’ll need to manually clear out the $this->load->_ci_cached_vars array between view calls.
A code comment in the Loader class describes another situation showing why this is the desired default behavior:
You can either set variables using the dedicated $this->load_vars()
function or via the second parameter of this function. We'll merge
the two types and cache them so that views that are embedded within
other views can have access to these variables.

Resources