How can combine different pages in codeigniter? - php

Let say I separate my page into 4 parts. One is banner, one is login, one is main, another is footer. Banner and Footer is static, it won't change. and login is based on different user right or login status, lastly the main is based on many thing to do it. So, I have 4 parts of element:
http://localhost:8888/my_app/index.php/static_page/banner
http://localhost:8888/my_app/index.php/static_page/footer
http://localhost:8888/my_app/index.php/user/login_fragment
http://localhost:8888/my_app/index.php/system/main_fragment
But the user only see one page, but it combine all the staff in...So, instead of using iframe to put them together, how can I let these page separate the logic, but can combine in one view? Thank you.

I want to share what I have done. Although not an original idea(do not remember from where I got), hopefully this will help you. I have an 'includes' [application/views/includes] folder, which contains the following files:
footer.php, header.php, navigation.php and template.php
Now the code in the template.php is as the following:
$this->load->view('includes/header');
$this->load->view($main_content);
$this->load->view('includes/footer');
For usage, let me give you an example:
$data = array (
'page_title' => 'Users Listing',
'title' => 'Users Listing',
'main_content' => 'users/showlist',
);
$this->load->view('includes/template', $data));
The elements in the $data array, will be available in the view [application/views/users/showlist.php] as $page_title, $title etc. You can also send arrays or HTML content.

Just call load->view multiple times
in your controller method:
function index()
{
$this->load->view("banner",array(/** some parameters if you want **/));
$this->load->view("main",array(/** some parameters if you want **/));
$this->load->view("footer"); // this one doesn't need parameters maybe
}
See the views documentation page
Note: within a view file itself (e.g. inside banner.php) you can call load-view again to insert a nested view.
Note2: you can also return the result of load->view into a variable if you don't want to output it right away, by adding a true parameter as the 3rd parameter:
$login_box = $this->load->view("login",array(),true);
// $login_box contains the view html.
echo $login_box; // or pass it as a parameter to another view if you want

First of all
$this->load->view('filename');
Can be used as many times as you want in the same controller function, and they will appear in the right order.
What you did is separate in controllers parts that must be used in the same controller. I suppose you have these in files like
/application/controllers/static_page.php
/application/controllers/user.php
/application/controllers/system.php
And, without massive modification of CodeIgniter, you can't call a controller from another controller, which is what was stopping you. If you have to use the same processing code for many functions, you have to make either a helper, that you can use anywhere, or the more elegant solution, that is having common controller functions in /libraries/MY_Controller.php.
MY_Controller.php would be called always before a controller is called
<?php
if (!defined('BASEPATH')) exit('No direct script access allowed');
class MY_Controller extends CI_Controller
{
function __construct()
{
parent::__construct();
// you can do any kind of processing here
// in example if you have some view counter
// this place is always called
}
function a_generic_function($rawdata)
{
// do some processing here
return $data;
}
}
Then, you will be able to use this function in any of your controllers:
$this->a_generic_function($rawdata);
Now, the smartest way to deal with a header+footer is making a "layout" file that contains both the header and the footer.
Here's an example of layout.php view:
<!doctype html>
<head>
<meta charset="utf-8">
<title><?php echo $title; ?></title>
</head>
<body>
<div id="container">
<header>This page has been made by <?php echo $user_name; ?>/header>
<div id="main" role="main">
<?php echo $main_content_view; ?>
</div>
<footer>Write your footer here</footer>
</div>
</body>
</html>
You see there's $main_content_view in the middle.
With this you will do, in your controller:
// add the HTML for the login to the variable
// TRUE means we don't output it in the browser, but put it in a String
$this->viewdata["main_content_view"] = $this->load->view('login', $data, TRUE);
// want to add more data? just ADD it to the variable, like a String
$this->viewdata["main_content_view"] += $this->load->view('main', $data, TRUE);
// done? send it to the layout, and pass it the $this->viewdata
$this->load->view('layout', $this->viewdata);
What else can you do with this? You can use the $this->viewdata like:
$this->viewdata["title"] = 'Function title';
$this->viewdata["user_name"] = $user_name;
so you can edit your layout as much as you want like any other view.

Phil Sturgeon has written a popular template library for Codeigniter which will do what you want in a smarter way than what has been described in the other answers so far. You can read its documentation here: http://philsturgeon.co.uk/demos/codeigniter-template/user_guide/
The documentation might take a while to understand because it lacks examples.
You can download the template library here: https://github.com/philsturgeon/codeigniter-template

Related

codeigniter parse content in template

Can someone help me to explain in which way is the best to organize views in codeigniter and make some template where header and footer will be same but content to change for every page? I use parse to send data from controller to view but don't know how to organize view in described way.
Also how to avoid php logic in view (if)?
There are two ways if your are not using a template library:
1. Request your partial views in your content view:
<?php $this->load->view('header') ?>
My content
<?php $this->load->view('footer') ?>
2. Create a layout view, pass the content as variable:
<html>
<body>
<?php echo $content ?>
</body>
In this case, in your controller:
// The true parameter means it will load the view, but just pass back as a string
$content = $this->load->view('mycontent', array(), TRUE);
// Display the layout with your content
$this->load->view('layout', compact('content'));
As asking about the logic, don't get too strict with it. if, for, foreach are okay in a template. Forexample if a user is logged in, show a menu.
This might help you regarding about the templating.
Controller:
public function index() {
$data = array(
'blog_title' => 'Home',
'blog_content' => 'Content goes here..',
'footer_data' => 'footer data here..'
);
$this->load->view(templates/header, $data);
$this->load->view(templates/content, $data);
$this->load->view(templates/footer, $data);
}
Note: imagine that templates is a directory inside your views folder. Inside your templates must be the header, content and footer.php files.

Codeigniter session does not work after including Controller in view

I was working on a site in which on right side I am displaying some fixed type of dynamic content like event calendar, login, register etc. right side bar name is right_view.php
So first I was doing like this that I was sending parameters in every function of controller's and then in my view I was accessing right side parameters by calling right view like this
<?php $this->load->view('right_view');?>
then after login I can get my username that is stored in session.
After that I thought it is not a good approach to send parameters in every functions I just make a controller named right.php and in this controller I am passing parameters to right_view.php and after that in my view I changed my code for callig righr_view like this
<?php include(base_url().'right');?>
It display right content as I do above but one changed happen that I cannot access any of session stored variable in right side bar.
Is session does not work after including controller in view?
You're basically wanting to do a template system but going about it the wrong way. And for the record no I don't think you can (or at least should) be loading controllers into views like that.
What you want is a template file something like this:
<?php
$this->load->view('templates/header', $title);
$this->load->view('templates/sidebar',$sidebar_content);
$this->load->view('pages/'.$main_content);
$this->load->view('templates/footer');
?>
Call that template.php
Then in your controller you'd do something like this:
public function welcome()
{
$data['main_content'] = 'welcome';
$data['title']='Welcome to REfficient.com!';
$data['sidebar_content'] = 'sidebar/no_sidebar';
$data['additionalHeadInfo'] ='';
$this->load->view('templates/template',$data);
}
So if you look at the template file the first line is loading the header and including the title variable to insert into the page (header, sidebar, maincontent and footer are all their own separate PHP pages) and so on.
Now what I did (since my layout was very similar to yours) is my main sidebar file has an if statement that says if logged in show x, if not show login form.
Note - the additionalHeadInfo variable is so I can have includes like jQueryUI or something on an individual page without loading it on pages that don't need it.

Within Codeigniter, how do I write a view file to a view file?

I have a thank_you.php file that simply contains the string "Thank you." formatted in a successful / green color.
I'm wanting to display this text on a specific region of the site, but not sure how to go about it. Within my main view file, I added the line:
<?php $this->template->add_region('success'); ?>
next to the "Submit" button.
Within my controller, I have a function that should, once called, display the view file "thank_you.php".
function greeter_thank_you() {
$this->template->write_view('success', 'thank_you.php');
}
I have the standard $alert, $content, $main, etc... regions within my Template file, but how do I echo this view file onto another view file? Is there some other way I need to go about it?
It seems you are using Collin Williams' CI Template library.
As far as I know, you can't define a region inside another one, so it is better to send the value of the internal region (which you called it success) into the main region.
If you are using $this->template->write(); method to write content to the main region:
Get the content of thank_you view file by using $this->load->view('thank_you', '', TRUE); and place it somewhere inside the second parameter of write().
If you are using $this->template->write_view() method:
Use the following:
$data = array(
'foo' => 'bar',
'baz' => 'qux',
'success' => $this->load->view('thank_you', '', TRUE)
);
$this->template->write_view('main', 'main_region_view_file_here', $data/*, TRUE*/);
And add the following inside the view file of the main region:
if (! empty($success)) {
echo $success;
}
I don't have any experience with Collin Williams' Template library, but I think this might do the trick.
By the way, If you had any problem, I'm all ears!
if you want to to load one view file within another view file.
Just type
$this->load->view('FolderPath/FileNameHere');
I Hope it solves your Problem.
Edit:
Or if You are Tying to Load another View after Performing some action on Button.
You can redirect your button to that controller.
and there you can write the above line.
if it is a anchor Button just put <a class="BtnClass" href="ControllerPathHere">Submit</a>
and if you are using some templates Library Please tell more about it.
In the controller, you want to buffer the view output to a variable, and pass the variables to the template. The third parameter in the view method allows you to return the view output as a string.
$viewData = array(
'main' => $this->load->view('thank_you.php', '', true)
);
$this->load->view('template.php', $viewData);
// access the main template data with $main in template.php
See the bottom of this page: http://ellislab.com/codeigniter/user-guide/general/views.html
1-You can pass it like this:
function greeter_thank_you()
{
$data = array();
$thank_page = $this->load->view('thank_you');
$data['thank_you'] = $thank_page;
$this->load->view('main',$data);
}
inside your main page
<html>
<body>
<div id='thank'>
<?=$thank_you?>
</div>
<!--The rest of your codes-->
</body>
</html>

Efficient Website Navigation with CodeIgniter

I'm working on a site where there can be up to 3 levels of hierarchy in the navigation.
main sections in the top header
sub-navigation on the left
optional sub-sub navigation below that
In the past, when I've rolled my own with PHP, I would create a file navigation.php holding a class and arrays for all the sections and sub sections and a couple of functions to output the navigation. I'd set variables on every page in the site (current_section ='', current_sub_section='') so the navigation function would know what to highlight.
In CodeIgniter, I'm wondering if this is still a good approach to use?
I'm going to assume that your main nav sections almost directly map to your controllers, ie.
Home | News | Events
In your top bar, maps to:
/home
/news
/events
If this is the case, you already have a simple way of selecting your nav array.
You can put an array of nav item-link pairs in your controller constructor & pass them along to a sub-view in your output.
Example:
class HomeController extends CI_Controller
{
private $nav;
public function __construct()
{
parent::__construct();
$this->nav = array(
array('Browse', site_url('news/browse')),
array('Edit', site_url('news/edit'))
);
$this->load->vars(array('NavigationArray' => $this->nav));
}
// ...
}
Now what you've done is auto-registered a variable in all your views $NavigationArray that contains an array of Display Name - Link pairs.
You can then load a basic Navigation View that builds up your subnav from that variable (as it's availiable everywhere).
<? foreach($NavigationArray as $entry): ?>
<?=$entry[0];?>
<? endforeach; ?>
And below that you can look for the existance of a sub-nav array that you could optionally set in your controller, or whatever (the third optional nav you talked about)
<? if(exists($SubNavigationArray)): ?>
<? foreach($SubNavigationArray as $entry): ?>
<?=$entry[0];?>
<? endforeach; ?>
<? endif; ?>
Please remember, this example is very basic, but this is generally how we pass data around, I wouldn't want you to put global variables anywhere and try to queue off them. Simply "load" variables into the view engine, and they'll be availiable when you go to render your views/subviews.
This way the controller controls what nav items get displayed.
Also note:
You can pass the variables explicitly instead of trusting they will exist in the scope of your view.
$this->load->view('myview', array('NavigationArray' => $this->nav));
Hope this helps.
Here's basically what I do to determine "active" links in Codeigniter:
$active_class = '';
$url = site_url('your/link/url');
if ($url == current_url())
{
$active_class = ' class="active"';
}
$link = '<a href="'.$url.'"'.$active_class.'>Link Text</a>";
Keep in mind this is a basic example and usually run in a loop. The best way depends on what your navigation array looks like, and what you consider to be "active" (f you want to "activate" links whose href partially match the url).
The best way is to use 3 different views, a top view, a left view and a bottom view then in your controller you can pass the apporiate vars to each view so you would do something like
$top[current] = something;
$top[current_sub] = somethingelse;
$this->load->view('top_nav', $top);
$this->load->view('left_nav',$left);
...
Then in your views you can handle the variables passed to them.

Codeigniter How to Dynamically create menu

So I have a menu that I want to generate a main menu based on the authenticated user's access level. No problem creating the menu, however I want to automatically create the generated menu in my "header" view. So in my controller I am calling the "header" view, but I don't want to pass this dynamic part of the header like this:
$data['menu'] = 'Some Generated HTML Menu';
$this->load->view('header',$data);
I would rather it already be included in my header file, but I'm not exactly sure how to do this (aside from adding the $data declaration from inside of my constructor).
I don't know if this will help you, but this was how I did my template system for the longest time before moving on to a more advanced method.
Top Head: views/inc/top_head.php
<html>
<head>
<!-- all of your imports you want across all pages -->
Bottom Head: views/inc/bottom_head.php
I do it this way so that I can split and add custom Javascript things and maybe bring in special case imports.
</head>
<body>
<div id="main_container">
<div id="navigation">
<?php
// DO YOUR NAVIGATION MAGIC HERE
if($is_logged_in) :
// BAM MAGIC DONE
else :
// No magic show here
endif;
?>
</div>
Footer: views/inc/footer.php
This is where you will put in your footer things etc....
</div>
</body>
Now we are at the point that we need to actually fill content in to the template
Index Page: /views/some_controller/index.php
<?php $this->load->view('inc/top_head.php'); ?>
<?php $this->load->view('inc/bottom_head.php;) ?>
<h1>Hello</h1>
<p>Some filler content and stuff I guess would go here...Of course</p>
<?php $this->load->view('inc/footer.php'); ?>
So there, we have a quick template system. Now to show you what I have done for a controller
<?php
class Some_Controller extends Controller {
public $page_data;
public function __construct() {
parent::__construct(); // Load parent constructor
// This is page data that we obviously don't want to keep retyping
$this->page_data = array(
'is_logged_in' => FALSE, // Obviously do some test here
'page_title' => 'Some Title'
);
}
public function index() {
$this->_load('some_controller/index');
}
/** Should think of a better name but meh */
private function _load($view) {
$this->load->view($view, $this->page_data);
}
}
I hope this helped in some way or another. Mind you this is a quick write up. If I really wanted this to go into production, I would have moved the _load function into a parent class and extended it. I would also probably move the page_data variable along with it.
You could just make $data['menu'] = an multi-dimension array of (button_name, url)'s. Then in the view you pass this array to a plugin which generates the html menu based on that array.

Categories