2010-09-09 12 views
8

Jaki byłby najlepszy sposób sprawdzenia bieżącego segmentu identyfikatora URI w widoku CodeIgniter? Próbuję użyć bieżącego segmentu URI [tj. $ this-> uri-> segment (1)], aby podświetlić bieżącą stronę na pasku nawigacji.Bieżący segment URI w CodeIgniter

Najlepszym że zorientowali się to zrobić

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

w każdym z moich kontrolerów, a następnie w pliku header.php, sprawdzić zmienną $ current_uri aby określić, która część nawigacji powinien być podświetlony. Jak wiecie, jest to bardzo męczący sposób robienia tego, ale brakuje mi lepszego sposobu na zrobienie tego.

Możliwe jest nawet rozszerzenie domyślnej klasy kontrolera, aby przekazać bieżący segment identyfikatora URI, ale nie jestem pewien, czy to działałoby, ani nawet jak to zrobić.

+1

Robiłem to samo i jestem bardzo ciekawy lepszego rozwiązania. – janosrusiczki

Odpowiedz

6

Sam używam dodatkowej funkcji podobnej do zakotwiczenia(). Ja nazywam to active_anchor(), i zajmuje wszystkie te same parametry plus inne (uri). Funkcja dodaje klasę "active", jeśli przekazany ciąg znaków pasuje do parametru url active_anchor().

Następnie powraca funkcji wykorzystujących funkcję kotwicy (wszystkim, że funkcja nie było ustalić, czy związek potrzebne klasa „aktywny” lub nie

EDIT:.

po prostu umieścić ten kod w plik o nazwie "MY_url_helper.php" .W ten sposób, gdy jest załadowany pomocnik url (faktycznie ładuję to auto, ponieważ prawie wszystkie moje widoki i tak go używają.) To także tylko szybki kod, całkiem pewny, że to zadziała Zasadniczo przyjmuje te same argumenty, co funkcja anchor(), ale także zmienną $ key. Dodaje klasę "active" do znacznika zakotwiczenia, jeśli klucz i adres URL są zgodne.

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

Podoba mi się to podejście. Gdzie mam umieścić tę funkcję? Zakładam, że muszę rozszerzyć jedną z klas CI, ale nie jestem pewien, który? – Jared

2

Też miałem ten sam problem, kiedy budowałem stronę klienta w Cakephp, przekazując te ciągi dla każdego elementu menu od kontrolera do obejrzenia, a następnie ponownie sprawdzając w celu wprowadzenia wyróżnienia do żmudnego co najmniej.

Dla niektórych z moich projektów teraz, zostały wykonawczych samo przez przechowywanie informacji strona dla każdej ze stron menu nawigacji w bazie, rzeczy takie jak nazwa strony, URL, tytuł, pozycja w menu nawigacji itp

Następnie na początku kontrolera przechowuję wszystkie te dane w tablicy: $pageinfo.

Obsługuję funkcję nawigacji za pomocą jednego kontrolera, który sprawdza segment URI i ładuje zawartość na podstawie tego.

Podświetlająca część jest pozostawiona do instrukcji if podczas generowania widoku, w której porównuję nazwę każdej strony z informacjami, które porzuciłem w $pageinfo.

Coś takiego ...

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

ten sposób nie muszę przekazać ciąg stałych (URI segmentów w danym przypadku) do widoku. To podejście typu CMS pozwala mi elastycznie dodawać kolejne pozycje do mojego menu, bez dodawania więcej kodu.

Pamiętam, że otrzymałem to z wiki strony kodera, nie mogę znaleźć w tej chwili linku do niego.

0

będę prawdopodobnie uzyskać podpalany dla sugeruje podejście po stronie klienta, ale to jest coś Użyłem w przeszłości, aby oznaczyć bieżącą stronę jako podświetlone: ​​

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

Wiedziałeś, że to jest niewłaściwe podejście, mimo że tak czy inaczej to zaleciłeś? –

2

ten prosty sposób i działa dobrze dla mnie ..

<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) oznacza, że ​​funkcja w ur kontrolera.

ale mam słabość, mam kłopoty, jeśli mogę umieścić widok kontroler indeksu, więc im wolno używać indeks funkcyjny (toruble w uri segmentu, dokonaj 2 bieżącą stronę w tym samym czasie ... czytaj ten http://ellislab.com/codeigniter/user-guide/libraries/uri.html

+0

Jeśli twoje kontrolery są zorganizowane w folderach, funkcja uri_segment (2) nie będzie już funkcją kontrolera. –

0

W każdy projekt CodeIgniter Zbierałem podstawowe informacje o żądaniu w MY_Controller:

Rozszerzam główny kontroler i wprowadzam logikę inicjalizacji, która musi się zdarzyć na każdej stronie. Obejmuje to uzyskanie informacji o kontrolerze i metodzie, która jest przekazany do widoku, jako krótki przykład:

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

Teraz w widoku takich jak nawigacji można wykorzystać te informacje tak:

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

mi się podoba, bo z trasy lub zmienia bieg może uzyskać dostęp do kontrolerów i metod z różnych adresów URL. W ten sposób ustalasz, czy łącze jest aktywne na podstawie kontrolera/metody obsługującej zawartość, a nie na podstawie adresu URL.

Te informacje mogą być ponownie wykorzystane w kontrolerach lub widokach z dowolnego powodu, a użytkownik nie musi ciągle pytać routera lub użytkownika, aby obliczyć informacje (co nie tylko jest nieefektywne, ale jest nieporęczne w pisaniu w kółko).

1
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>