Current URI Segment in CodeIgniter
What would be the best way to check for the current URI segment in a CodeIgniter view? What I am trying to do is use the current URI segment [i.e. $this->uri->segment(1)] in order to highl开发者_Go百科ight the current page on the navigation bar.
The best that I have figured out is to do
$data['current_uri'] = $this->uri->segment(1);
$this->load->view('header', $data);
in each of my controllers and then in the header.php file, I check the $current_uri variable to determine which part of the navigation should be highlighted. As you know, this is a very tedious way of doing it, but I'm at a loss of a better way to do this.
It may even be possible to extend the default Controller class to pass the current URI segment, but I'm not sure if this would work, or even how to go about doing it.
I myself use an extra function similar to anchor(). I call it active_anchor(), and it takes all the same parameters plus another (the uri). The function then adds the class 'active' if the uri string passed matches the active_anchor() url paramter.
Then the function returns using the anchor function (all that the function did was determine if the link needed the class 'active' or not.
EDIT:
I just put this code in a file called 'MY_url_helper.php'. That way, when the url helper is loaded (I actually auto load that one since pretty much all of my views use it anyway.) This is just some quick code too, pretty sure it would work. Basically it takes the same arguments as the anchor() function, but also the $key variable. It appends a class of "active" to the anchor tag if the key and url match.
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
if ( ! function_exists('active_anchor'))
{
function active_anchor($url = NULL, $title = NULL, $key = NULL, $params = array())
{
if ($url && $key)
{
if($key == $url)
{
if (array_key_exists ('class' , $params))
{
$params['class'] .= ' active';
}
else
{
$params['class'] = 'active';
}
}
}
return anchor($url, $title, $params);
}
}
Simple way to check the uri segment in view,
Add some code if matches found.
<li class="<?php echo (strcmp($this->uri->segment(2),'test')==0)?'active':''; ?>"><li>
<li class="<?php echo (strcmp($this->uri->segment(2),'test1')==0)?'active':''; ?>"><li>
<li class="<?php echo (strcmp($this->uri->segment(2),'test2')==0)?'active':''; ?>"><li>
I also had the same problem when I was building a customer website in Cakephp, passing those strings for every menu item from controller to view, then checking again in view for implementing the highlighting to tedious to say the least.
For some of my projects now, I have been implementing the same by storing the page information for each of the navigation menu pages in database, things like page name, url, title, position in navigation menu etc.
Then at the start of controller, I store all this data in an array say $pageinfo
.
I handle the navigation functionality via a single controller that checks the URI segment and loads the content based on that.
The highlighting part is left to an if statement when generating the view, where I compare each page name to the information I dumped in $pageinfo
.
Something like this...
foreach ($navi_menu as $links) {
if ( $links['title'] == $pageinfo['title'] ) {
// Highlight here
}
else {
// No highlight
}
}
This way I don't need to pass the string constants (uri segments in your case) to the view. This CMS-kinda-approach allows me to flexible in adding further items to my menu, without adding more code.
I remember getting this from a codeigniter wiki, can't find the link to it right now.
this simple way and running well for me..
<li class="<?=($this->uri->segment(2)==='test')?'current-menu-item':''?>"><?php echo anchor ('home/index','HOME'); ?></li>
<li class="<?=($this->uri->segment(2)==='blog')?'current-menu-item':''?>"><?php echo anchor ('home/blog','BLOG'); ?></li>
<li class="<?=($this->uri->segment(2)==='bla..bla')?'current-menu-item':''?>"><?php echo anchor ('home/blog','bla..bla'); ?></li>
uri_segment(2) that mean function in ur controller.
but have a weakness, i have trouble if i put view in index controller, so im not use function index ( toruble in uri segment, make 2 current page in same time... read this http://ellislab.com/codeigniter/user-guide/libraries/uri.html
I'll probably get flamed for suggesting a client-side approach, but this is something I've used in the past to mark the current page as highlighted:
var path = location.pathname.substring(1);
if ( path )
$('#navigation a[href$="' + path + '"]').parents('li').attr('class', 'current');
In every CodeIgniter project I gather some basic information about the request in MY_Controller.
I extend the core controller and put in some initialization logic that needs to happen on every page. This includes getting the information about the controller and method, which is passed to the view. As a short example:
class MY_Controller extends CI_Controller
{
protected $_response_type = 'html';
protected $_secure;
protected $_dir;
protected $_controller;
protected $_method;
protected $_template;
protected $_view;
protected $_user;
public function __construct()
{
parent::__construct();
// Gather info about the request
$this->_secure = ! empty($_SERVER['HTTPS']);
$this->_dir = $this->router->fetch_directory();
$this->_controller = $this->router->fetch_class();
$this->_method = $this->router->fetch_method();
// set the default template and view
$this->_template = 'default';
$this->_view = $this->_dir . $this->_controller . '/' . $this->_method;
}
/**
* Performs operations right before data is displayed.
*
* @access public
* @return void
*/
public function _pre_display()
{
if ($this->_response_type === 'html') {
$this->load->vars(array(
'user' => $this->_user
));
}
elseif ($this->_response_type === 'json') {
$this->_template = 'json';
$this->_view = NULL;
}
else {
show_error('Invalid response type.');
}
$this->load->vars(array(
'is_secure' => $this->_secure,
'controller' => $this->_controller,
'method' => $this->_method
));
}
}
Now in a view such as the navigation you can use that information like this:
<a href="<?php echo site_url('products') ?>"<?php echo ($controller === 'products') ? ' class="selected"' : ''; ?>>Products</a>
I like it because with routes or rewrites you may access controllers and methods from different URLs. This way you set whether the link is active based on the controller/method that is serving up the content and not based on the URL.
Also, this information can be reused within your controllers or views for any reason and you are not continually asking the router or uri to calculate the information (which not only is inefficient, but is cumbersome to write over and over).
精彩评论