Текущий сегмент URI в CodeIgniter

каков был бы лучший способ проверить текущий сегмент URI в представлении CodeIgniter? Я пытаюсь использовать текущий сегмент URI [т. е. $this->uri - >segment(1)], чтобы выделить текущую страницу на панели навигации.

лучшее, что я понял, это сделать

$data['current_uri'] = $this->uri->segment(1);
$this->load->view('header', $data);

в каждом из моих контроллеров, а затем в заголовке.php-файл, я проверяю переменную $current_uri, чтобы определить, какая часть навигации должна быть выделена. Как и ты знаете, это очень утомительный способ сделать это, но я не знаю лучшего способа сделать это.

возможно, даже можно расширить класс контроллера по умолчанию, чтобы передать текущий сегмент URI, но я не уверен, что это сработает или даже как это сделать.

6 ответов


Я сам использую дополнительную функцию, подобную anchor (). Я называю его active_anchor (), и он принимает все те же параметры плюс другой (uri). Затем функция добавляет класс "active", если переданная строка uri соответствует параметру url-адреса active_anchor ().

затем функция возвращается с помощью функции anchor (все, что функция сделала, это определила, нужна ли ссылка классу "active" или нет.

EDIT:

Я просто поместил этот код в файл называется ' MY_url_helper.на PHP'. Таким образом, когда помощник url загружен (я фактически автоматически загружаю его, так как почти все мои представления используют его в любом случае.) Это просто какой-то быстрый код тоже, уверен, что он будет работать. В основном он принимает те же аргументы, что и функция anchor (), но также и переменную $key. Он добавляет класс "active" к тегу привязки, если ключ и url совпадают.

<?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);
    }
}

у меня также была такая же проблема, когда я строил веб-сайт клиента в Cakephp, передавая эти строки для каждого пункта меню из контроллера в вид, а затем снова проверяя, чтобы реализовать выделение, чтобы утомительно, мягко говоря.

для некоторых из моих проектов теперь я реализую то же самое, сохраняя информацию о странице для каждой из страниц меню навигации в базе данных, такие вещи, как имя страницы, url, заголовок, позиция в меню навигации так далее.

затем в начале контроллера я храню все эти данные в массиве say $pageinfo.

я обрабатываю функциональность навигации с помощью одного контроллера, который проверяет сегмент URI и загружает контент на основе этого.

часть подсветки остается для оператора if при создании представления, где я сравниваю каждое имя страницы с информацией, которую я сбросил в $pageinfo.

что-то вроде этого...

foreach ($navi_menu as $links) {
    if ( $links['title'] == $pageinfo['title'] ) {
      // Highlight here
    }
    else {
      // No highlight
    }
}

таким образом, я не необходимо передать строковые константы (сегменты uri в вашем случае) в представление. Этот CMS-kinda-подход позволяет мне гибко добавлять дополнительные элементы в мое меню, не добавляя больше кода.

Я помню, что получил это от Codeigniter wiki, не могу найти ссылку на него прямо сейчас.


этот простой способ и работает хорошо для меня..

<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), что означает функцию в контроллере ur.

но есть слабость, у меня проблемы, если я помещаю представление в контроллер индекса, поэтому я не использую индекс функции ( toruble в сегменте uri, сделайте 2 текущую страницу в то же время... прочтите это http://ellislab.com/codeigniter/user-guide/libraries/uri.html


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>

Я, вероятно, вспыхну за предложение подхода на стороне клиента, но это то, что я использовал в прошлом, чтобы отметить текущую страницу как выделенную:

var path = location.pathname.substring(1);
if ( path )
 $('#navigation a[href$="' + path + '"]').parents('li').attr('class', 'current');

в каждом проекте CodeIgniter я собираю некоторую базовую информацию о запросе в MY_Controller.

я расширяю основной контроллер и помещаю некоторую логику инициализации, которая должна произойти на каждой странице. Это включает в себя получение информации о контроллере и методе, который передается в представление. В качестве короткого примера:

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
        ));
    }
}

теперь в представлении, таком как навигация, вы можете использовать эту информацию следующим образом:

<a href="<?php echo site_url('products') ?>"<?php echo ($controller === 'products') ? ' class="selected"' : ''; ?>>Products</a>

мне это нравится, потому что с маршрутами или перезаписями вы можете получить доступ к контроллерам и методам из разных URL-адресов. Таким образом, вы устанавливаете, активна ли ссылка на основе контроллера/метода, который обслуживает содержимое, а не на основе URL-адреса.

кроме того, эта информация может быть повторно использована в ваших контроллерах или представлениях по любой причине, и вы не постоянно просите маршрутизатор или uri вычислить информацию (которая не только неэффективна, но и громоздка для записи снова и снова).