CodeIgniter菜单/导航困境

时间:2012-10-22 16:21:16

标签: php codeigniter navigation

我正在尝试CodeIgniter和整个MVC模式。我已经安装了Colin Williams' Template library,但在尝试考虑包含两个菜单/导航的正确方法时遇到困难:一个通用(可能在顶部)和一个专用于每个控制器的侧边栏。

无论哪种方式,他们的位置都不相关,我正在考虑代码的一般结构。现在我的模型中有一个函数get_menu(),并且在加载侧边栏的部分模板视图时,它的返回值作为参数给出。或者我应该在控制器中执行此操作?

我的一个伙伴给了我建议,不要使用MY_Controller扩展默认控制器或模型,但我不知道何时实施一般菜单?或者我应该在模板配置文件中对此进行硬编码吗?

我找不到此类任务的指导原则。无论我走到哪里,我都会找到一个新的解决方案,其中很多都不漂亮,而其他很多都有很多重复的代码。

编辑。我已更新了我的代码。我还没有决定如何编写顶级导航(可能在MY_Controller,以便我可以突出显示当前页面。)

MY_Controller.php

abstract class MY_Controller extends CI_Controller {
    protected $_nav;

    const CONTENT_REGION = 'content';
    const NAV_REGION = 'nav';
    const TITLE_REGION = 'title';

    const SIDEBAR_NAV_TEMPLATE = 'templates/sidebar_nav';

    public function __construct() {
        parent::__construct();
        $this->_load_nav();
    }

    abstract protected function _get_nav();

    protected function _load_nav() {
        $this->_nav = array('nav' => $this->_get_nav());
    }

    protected function _render() {
        $args = func_get_args();
        $n = func_num_args() - 1;

        if ($n < 2) {
            return;
        }

        $this->template->write(self::TITLE_REGION, $args[0]);

        for ($i = 1; $i < $n; $i++) {
            $this->template->write_view(self::CONTENT_REGION, $args[$i], $args[$n]);
        }

        $this->template->write_view(self::NAV_REGION, self::SIDEBAR_NAV_TEMPLATE, $this->_nav);
        $this->template->render();
    }

    protected function _set_active_view($active) {
        if ($active !== null && isset($this->_nav['nav'][$active])) {
            $this->_nav['nav'][$active]['class'] .= ' active';
        }
    }
}

collection.php

class Collection extends MY_Controller {
    public function __construct() {
        parent::__construct();
        $this->load->model('collection_model');
    }

    protected function _get_nav() {
        return array(
            'collection/view' => array(
                'href'  => 'collection/view',
                'value' => 'View collection',
                'class' => 'icon-film'
            ),
            'collection/add' => array(
                'href'  => 'collection/add',
                'value' => 'Add title',
                'class' => 'icon-plus-sign'
            )
        );
    }

    public function index() {
        $this->view();
    }

    public function view() {
        $data['list'] = $this->collection_model->get_list();
        $this->_set_active_view('collection/view');
        $this->_render('View Collection', 'collection/view', $data);
    }
}

sidebar_nav.php

<ul class="nav nav-list bs-docs-sidenav">
    <?php

    foreach ($nav as $item) {
        echo '<li';

        if ($item['class'] !== null || $item['class'] !== '') {
            echo ' class="' . $item['class'] . '"';
        }

        echo '><a href="' . $item['href'] . '">' . $item['value'] . '</a></li>';
    }

    ?>
</ul>

这看起来怎么样?我可以在_render($title, $view, $data)中编写一个函数MY_Controller来完成所有模板的工作。你觉得怎么样?

我一直在考虑的另一个解决方案是删除_get_nav()并从配置文件中加载所需的导航数据,但我不知道如何执行此操作。

1 个答案:

答案 0 :(得分:0)

你的“好友”有什么可能的原因告诉你不要扩展控制器类?这种类型的重复性东西正是这个功能的用途......使用getMenu等功能创建MY_Controller,在整个站点中经常使用其他功能,然后只使集合扩展MY_Controller而不是CI_Controller。

我们不仅扩展了CI控制器,还将MY_Controller扩展到User_Controller和Admin_Controller,以包含仅供这些用户使用的特定功能。

我真的不能为我的生活想象为什么有人会告诉你不要这样做。