I used multiple layouts in Laravel using code as below, it works.
class UsersController extends BaseController {
public $layout = 'layouts.default';
...
}
But now I want to change the layout in Method (In UsersController)
public function myFunc(){
//I want to change myFunc's layout to 'default2'
$this->layout->content = View::make('user.myfunc');
}
How can I do? Because when I use $this->layout = 'layouts.default2'
it always returns me ErrorException: Attempt to assign property of non-object
You can use this in your controller method :
public function myFunc(){
$this->layout = View::make('layouts.default2');
$this->layout->content = View::make('user.myfunc');
}
Related
I am creating a master controller so that every other controllers on my app extend the master (MY_Controller).
My problem is how to make loading a model more abstract, let me show you the code to better explain.
class MY_Controller extends CI_Controller
{
protected $model;
function __construct()
{
parent::__construct();
}
function get($order_by)
{
$this->load->model($this->model);
$query = $this->$this->model->get($order_by);
return $query;
}
}
I declare a protected variable $model in the master controller so that on the extending controller i can asign it a value:
class Home extends MY_Controller {
public function __construct() {
parent::__construct();
$this->model = "home_model";
}
public function index()
{
$test = $this->get('id');
}
}
The problem is that on MY_Controller i cant load the model
$this->$this->model->get();
i get the following error: Message: Object of class Home could not be converted to string
any help will be appreciated , thank you !
Why do not save the value you assign to protected global $model variable in a variable inside the function as such:
class MY_Controller extends CI_Controller{
protected $model;
function __construct(){
parent::__construct();
}
function get($order_by){
$_model = $this->model // I added this line.
$this->load->model($_model); // I modified this line.
$query = $this->$_model->get($order_by); // I modified this line.
return $query;
}
}
The $this->$this->model->get() is your problem. If you want to use an object property ($this->model) inside a chain like this, you need to wrap it in braces: $this->{$this->model}->get().
In my controller I want to declare a global variable which will always fetch all areas from my db
currently I'm passing $data['dropdowns']
in all methods in my class
{
$data['dropdowns']=loading some other model method
$this->load->view('commons/header',$data);
}
{
$data['dropdowns']=loading some other model metod
$this->load->view('commons/header',$data);
}
{
$data['dropdowns']=loading some other model metod
$this->load->view('commons/header',$data);
}
{
$data['dropdowns']=loading some other model metod
$this->load->view('commons/header',$data);
}
the thing is I want to now send $data['area'] to all the views without having to declare it again and again in each method
$data['area']= $this->area_model->get_all_locations();
You want to add global variable , but as per my suggest to use global function to use any where to using to send parameter, so please check below my code.
Note : please load your model in application/config/autoload.php file
This is simple demo :
controller
{
$data['dropdowns']=$this->your_model_name->get_records('table_name','select field like id, name');
$this->load->view('commons/header',$data);
}
{
$data['dropdowns']=$this->your_model_name->get_records('table_name','select field like id, name,user_name');
$this->load->view('commons/header',$data);
}
Your model
function get_records($table_name,$field_name)
{
$this->db->select("$field_name");
$this->db->from("$table_name");
$query=$this->db->get();
return $query->result_array();
}
create a base_controller and placed in application/core
class base_controller extends CI_Controller
{
public $area = array();
function __construct()
{
// Call the Controller constructor
parent::__construct();
$this->get_area();
}
public function get_area() {
$this->load->model('area_model');
$this->area= $this->area_model->get_all_locations();
}
}
now $this->area is available in all controller which extends base_controller and all common functionality you can put here
class homepage extends base_controller{
function __construct()
{
// Call the Controller constructor
parent::__construct();
}
public function index()
{
$data = $this->area; // call this wherever u need
$this->load->view('commons/header',$data);
}
}
importantly $this->area; one can use directly inside view
Create a helper for your custom functions
Eg: custom_helper.php then load your custom helper in autoload.php
In custom_helper.php, create a function for getting area.
if (!function_exists('get_area')) {
function get_area() {
$CI = & get_instance();
$area= $CI->area_model->get_all_locations();
return $area;
}
}
You can call get_area() in your views without declaring in controllers..
Here is my controller code
public function index()
{
$this->load->model("mod_home");
$data['avoinics'] = $this->mod_home->getAvoinics();
$data['dir']="home";
$data['page']="index";
$this->load->view('main',$data);
}
for another page
public function about()
{
$this->load->model("mod_home");
$data['avoinics'] = $this->mod_home->getAvoinics();
$data['dir']="home";
$data['page']="about";
$this->load->view('main',$data);
}
But i don't want to send $data['avoinics'] again again. Is there any way to access a data from anypage.
How to use same data in a single view more than time.
foreach($avoinics as $avoinics):
$name=$avoinics->sc_name;
echo '<li>'.$name.'</li>';
endforeach;
if i use it again on same view page it's sowing error...
Yes, you can:
Create a global array
private $data = array();
In constructor
$this->load->model("mod_home");
$this->data['avoinics'] = $this->mod_home->getAvoinics();
Now your function will look like this
public function index() {
$this->data['dir']="home";
$this->data['page']="index";
$this->load->view('main',$this->data);
}
For second part, do not change the variable value
foreach($avoinics as $record){
echo '<li>'.$record['name'].'</li>';
}
$avoinics is intact now. You can use it again until you do not modify it.
A good example you might easily understand is when you need to call certain scripts or css files for a specific controller. You won't call it in every single page but yes in the constructor.
class yourController extends CI_Controller
{
private $data;
public function __construct()
{
$this->data['css'] = array('file1.css', 'file2.css');
$this->data['js'] = array('jquery.min.js', 'jquery-ui.min.js');
}
public function index()
{
$this->load->view('yourView', $this->data);
}
public function about()
{
$this->load->view('yourView', $this->data);
}
}
I recommend you to extend core ci_controller with my_controller and declare there your variable in constructor. Then in your new controllers extend your my_controller where you will have variable declaration.
I have something like this :
class AController extends BaseController
{
protected $layout = "templates.layouts.master";
protected $data = "something";
public function alt()
{
// this is wrong
// i want to override "templates.layouts.master"
// missing something obviously here
$this->layout = ??? what should do?
$this->layout->content = View::make("content", $this->data);
}
}
In method alt, I wish to use different layout than the default "templates.layouts.master".
I have very limited laravel 4 knowledge. This maybe something easy to achieve, but is beyond my knowledge.
Possible solutions that I forsee:
define a construct method, and detect what is the current method, and set a different value for $layout (However, I not sure how to get the current method name).
do an assignment like what I put in above.
Which is the correct way?
You can set the layout to be another view per method:
class AController extends BaseController
{
protected $layout = "templates.layouts.master";
protected $data = "something";
public function alt()
{
$this->layout = View::make('templates.layouts.alt');
$this->layout->content = View::make("content", $this->data);
}
}
If you check out the BaseController, you'll see that all it does is call View::make() to set the layout view. You can do the same to over-ride its default.
OK, solution 1 seems to be possible, but I think is fugly :
class AController extends BaseController
{
public function __construct()
{
if (Request::is("..."))
{
$this->layout = "alternative layout";
}
}
}
I am trying to get scroll news in any page of the website from database without having to pass the variable in every controller of the site. So I decided to use hooks instead of passing scroll variable in every controller.
I did create a class like this
class Scroll
{
function getScroller()
{
$data = array();
$CI =& get_instance();
$CI->db->where('a_status','active');
$CI->db->limit(4);
$CI->db->order_by('id','desc');
$Q = $CI->db->get('news');
if($Q->num_rows() > 0){
foreach($Q->result_array() as $row){
$data[] = $row;
}
}
$Q->free_result();
return $data;
}
}
What I get now is
Severity: Notice
Message: Trying to get property of non-object
Call to a member function get() on a non-object in E:\xampp\htdocs\
Can anyone please help me how to do this ? Thanks I want to get scrollernews in any controller's view automatically without having to pass in each controller. Thanks
If you are defining that on a view level, there is no need for that.
You can define db requests directly in a view.
Other approach would be to have separated controller which with separate view and load it in the page through iframe. It's often used for "web widgets" that can be later on loaded in to another pages.
Extending the core class of CI Controller will should cause you less troubles.
http://ellislab.com/codeigniter/user-guide/general/core_classes.html
application/core/MY_Controller.php
class MY_Controller extends CI_Controller {
public function __construct() {
parent::__construct();
//By do this, all controllers who use this class as parent controller
//will have $news in their views
$this->load->vars(array(
'news' => array()
));
}
}
application/controller/welcome.php
class Welcome extends MY_Controller {
public function index()
{
$this->load->view('welcome_message');
}
}
application/views/welcome_message.php
var_dump($news);
use separated library or helper and call that method on controller's constructs like :
class My_Controller extends CI_Controller(){
function __construct(){
parent::__construct();
//load your library
//call your library method
}
}