【问题标题】:Current URI Segment in CodeIgniterCodeIgniter 中的当前 URI 段
【发布时间】:2011-04-10 01:35:29
【问题描述】:

在 CodeIgniter 视图中检查当前 URI 段的最佳方法是什么?我想做的是使用当前的 URI 段 [即$this->uri->segment(1)] 以便在导航栏上突出显示当前页面。

我认为最好的方法是做

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

在我的每个控制器中,然后在 header.php 文件中,我检查 $current_uri 变量以确定应该突出显示导航的哪一部分。如您所知,这是一种非常乏味的方法,但我不知道如何更好地做到这一点。

甚至可以扩展默认的 Controller 类以传递当前的 URI 段,但我不确定这是否可行,甚至不确定如何去做。

【问题讨论】:

  • 我一直在做同样的事情,我很好奇更好的解决方案。

标签: php codeigniter


【解决方案1】:

我自己使用了一个类似于anchor() 的额外函数。我称之为active_anchor(),它接受所有相同的参数加上另一个(uri)。如果传递的 uri 字符串与 active_anchor() url 参数匹配,则该函数会添加类 'active'。

然后该函数使用锚函数返回(该函数所做的只是确定链接是否需要“活动”类。

编辑:

我只是将这段代码放在一个名为“MY_url_helper.php”的文件中。这样,当加载 url 帮助程序时(我实际上自动加载那个帮助程序,因为我几乎所有的视图都使用它。)这也只是一些快速代码,很确定它会工作。基本上,它采用与 anchor() 函数相同的参数,但也采用 $key 变量。如果 key 和 url 匹配,它会在锚标签上附加一个“active”类。

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

【讨论】:

  • 我喜欢这种方法。我会把这个功能放在哪里?我假设我需要扩展其中一个 CI 类,但我不确定是哪个?
【解决方案2】:
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>

【讨论】:

    【解决方案3】:

    当我在 Cakephp 中构建客户网站时,我也遇到了同样的问题,将每个菜单项的这些字符串从控制器传递到视图,然后再次检查视图以实现突出显示,至少可以说是乏味的。

    对于我现在的一些项目,我一直在通过将每个导航菜单页面的页面信息存储在数据库中来实现相同的功能,例如页面名称、url、标题、导航菜单中的位置等。

    然后在控制器开始时,我将所有这些数据存储在一个数组中,比如$pageinfo

    我通过一个控制器处理导航功能,该控制器检查 URI 段并基于该控制器加载内容。

    高亮部分留给生成视图时的 if 语句,在此我将每个页面名称与我在 $pageinfo 中转储的信息进行比较。

    这样的……

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

    这样我就不需要将字符串常量(在您的情况下为 uri 段)传递给视图。这种 CMS-kinda-approach 让我可以灵活地向菜单中添加更多项目,而无需添加更多代码。

    我记得我是从一个 codeigniter wiki 获得的,现在找不到它的链接。

    【讨论】:

      【解决方案4】:

      这种简单的方法对我来说运行良好..

      <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) 表示你的控制器中的功能。

      但有一个弱点,如果我将视图放在索引控制器中,我会遇到麻烦,所以我不使用函数索引(在 uri 段中使用 toruble,同时创建 2 个当前页面...阅读此http://ellislab.com/codeigniter/user-guide/libraries/uri.html

      【讨论】:

      • 如果您将控制器组织在文件夹中,那么 uri_segment(2) 将不再是控制器功能。
      【解决方案5】:

      我可能会因为提出客户端方法而受到抨击,但这是我过去用来将当前页面标记为突出显示的方法:

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

      【讨论】:

      • 您知道这是错误的方法,但您还是推荐了它?
      【解决方案6】:

      在每个 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 计算信息(这不仅效率低下,而且一遍又一遍地写入很麻烦)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-06-19
        • 2012-06-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多