簡體   English   中英

Codeigniter:構建部分視圖的最佳方式

[英]Codeigniter: Best way to structure partial views

如何在Codeigniter中構建以下頁面?

替代文字

我想為每個部分創建單獨的控制器

  1. 左導航
  2. 內容導航
  3. 登錄名
  4. 排行榜

排除內容部分(因為此更改取決於左側導航欄和內容導航欄中用作有點子菜單的鏈接)。 所有其他部分保持大致相同

我想過:

Class User_Profile extends Controller
{

    function index()
    {
        $this->load_controller('Left_Nav');
        $this->load_controller('Content_Nav');
        $this->load_controller('Login_Name');
        $this->load_controller('Leaderboard', 'Board');

        $this->Left_Nav->index(array('highlight_selected_page' => 'blah'));

        $this->load('User');

        $content_data = $this->User->get_profile_details();

        $this->view->load('content', $content_data);

        $this->Login_Name->index();
        $this->Board->index();
    }

}

顯然這個load_controller不存在,但是這個功能很有用。 每個部分的控制器從模型中獲取所需的數據,然后通過$this->view->load()加載頁面

在新聞,用戶,關於我們等所有左側導航鏈接中使用此代碼可能會令人頭疼。但是,然后再次並非每個導航鏈接都包含所有這些部分,因此我需要將這些部分作為“部分”的靈活性視圖”

誰能建議更好的方法呢?

@Reinis的回答可能正確地針對小於2.0的舊版本的CI正確地點擊了,但是從那以后很多都發生了變化,所以我想我會用我所做的最新方法回答這個問題。

其中大部分類似於@Reinis方法,也在這里描述: http ://codeigniter.com/wiki/MY_Controller_-_how_to_extend_the_CI_Controller

不過這是我做過的更新:

步驟1:創建一個MY_Controller.php文件並將其存儲在/ application / core中

第2步:在MY_Controller.php文件中輸入以下內容:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class MY_Controller extends CI_Controller {

    function __construct()
    {
        parent::__construct();
    }

    function _output($content)
    {
        // Load the base template with output content available as $content
        $data['content'] = &$content;
        echo($this->load->view('base', $data, true));
    }

}

步驟3:創建一個基於MY_Controller.php的樣本控制器,在這種情況下,我將在application / controllers /中創建一個welcome.php控制器,其中包含以下內容:

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Welcome extends MY_Controller {

    function __construct()
    {
        parent::__construct();
    }

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

}

設置好這些控制器后,請執行以下操作:

步驟4:在/ application / views中創建一個基本視圖並命名文件base.php,該文件的內容應類似於:

<!DOCTYPE html>
<!--[if IE 7 ]><html lang="en" class="ie7"><![endif]-->
<!--[if IE 8 ]><html lang="en" class="ie8"><![endif]-->
<!--[if gt IE 8]><!--><html lang="en"><!--<![endif]-->
    <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
        <title></title> 
        <link rel="stylesheet" href="<?php echo base_url(); ?>stylesheets/reset.css" media="screen" />
    </head>
    <body>
        <div id="section_main">
            <div id="content">
                <?php echo $content; ?>
            </div>
        </div>
        <?php $this->load->view('shared/scripts.php'); ?>
        </div>
    </body>
</html>

步驟5:在/ application / views中創建另一個視圖並將此視圖命名為welcome_message.php,該文件的內容將為:

<h1>Welcome</h1>

完成所有這些后,您應該看到以下輸出:

<!DOCTYPE html>
<!--[if IE 7 ]><html lang="en" class="ie7"><![endif]-->
<!--[if IE 8 ]><html lang="en" class="ie8"><![endif]-->
<!--[if gt IE 8]><!--><html lang="en"><!--<![endif]-->
    <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
        <title></title> 
        <link rel="stylesheet" href="http://somedomain.local/stylesheets/reset.css" media="screen" />
    </head>
    <body>
        <!-- BEGIN: section_main -->
        <div id="section_main">
            <div id="content">
                <h1>Welcome</h1>
            </div>
        </div>
        <!-- END: section_main -->
        <script src="/path/to/js.js"></script>
        </div>
    </body>
</html>

如您所見, <h1>Welcome</h1>已放入基本模板。

資源:

希望這可以幫助其他人遇到這種技術。

我不能保證這是最好的方法,但我創建了一個這樣的基本控制器:

class MY_Controller extends CI_Controller {

    public $title = '';
    // The template will use this to include default.css by default
    public $styles = array('default');

    function _output($content)
    {
        // Load the base template with output content available as $content
        $data['content'] = &$content;
        $this->load->view('base', $data);
    }

}

名為“base”的視圖是一個模板(包含其他視圖的視圖):

<?php echo doctype(); ?>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <?php $this->load->view('meta'); ?>
    </head>
    <body>
        <div id="wrapper">
            <?php $this->load->view('header'); ?>

            <div id="content">
                <?php echo $content; ?>
            </div>

            <?php $this->load->view('footer'); ?>
        </div>
    </body>
</html>

這實現了每個控制器將其輸出包裝在基本模板中,並且該視圖具有有效的HTML而不是在一個視圖中打開標記而在另一個視圖中關閉。 如果我想讓特定的控制器使用不同的模板或不使用模板,我可以覆蓋magic _output()方法。

實際的控制器看起來像這樣:

class Home extends MY_Controller {

    // Override the title
    public $title = 'Home';

    function __construct()
    {
        // Append a stylesheet (home.css) to the defaults
        $this->styles[] = 'home';
    }

    function index()
    {
        // The output of this view will be wrapped in the base template
        $this->load->view('home');
    }
}

然后我可以在我的視圖中使用它的屬性(這是填充<head>元素的'meta'視圖):

echo "<title>{$this->title}</title>";
foreach ($this->styles as $url)
    echo link_tag("styles/$url.css");

我喜歡我的方法,因為它尊重DRY原則,頁眉,頁腳和其他元素只包含在代碼中一次。

我的模板庫可以處理所有這些。 您可以創建一個(或多個)布局文件,其中包含部分內容以及主體內容所在位置的標記。

語法簡單如下:

// Set the layout: defaults to "layout" in application/views/layout.php
$this->template->set_layout('whatever') 

// Load application/views/partials/viewname as a partial
$this->template->set_partial('partialname', 'partials/viewname');

// Call the main view: application/views/bodyviewname
$this->template->build('bodyviewname', $data); 

簡單吧?

將其中的一些放入MY_Controller,它更容易。

你考慮過模板嗎? 有很多不錯的搜索 - 查看CI維基。

模板或多或少地完全符合您的要求。 您可以定義一個主模板和“部分”,每次都會為您加載這些模板和“部分”

不想插入太多,所以這可能會讓你開始 - CI中的模板庫

我會制作一個MY_Controller來處理這一切。 您可以使用布局(模板)/導航庫來生成所有布局,導航,顯示/突出顯示所選菜單項,加載視圖等。

如果你為每個頁面部分使用一個控制器,我會說這不是正確的方法。 您可以為此使用視圖和嵌套視圖。

我喜歡Phil Sturgeon提到的。 雖然它被認為是非常復雜的我真的很喜歡magento的模板結構。

靈感來自於這種結構化方式,我創造了我的邏輯,(它根本不是很好,但它很簡單,也許我可以覆蓋 - >視圖加載器並使它接受某種對象作為模板名稱和比根據需要加載結構)

第一 :必須非常負責任地使用這種方法(您可以在模板所需的控制器/方法中准備數據!

第二 :模板需要准備和正確組織。

這就是我做的:

  • 在每個控制器中我都有Array類型的屬性,如下所示:

     class Main extends CI_Controller { public $view = Array( 'theend' => 'frontend', 'layout' => '1column', 'mainbar' => array('content','next template file loaded under'), 'sidebar' => array('generic','next template file loaded under'), 'content' => '', ); 
  • 在我想要使用以前的結構的每個方法中,如果我想稍微更改它,我會這樣寫:

     public function index() { $data['view'] = $this->view; // i take/load global class's attribute $data['view']['mainbar'] = Array('archive','related_posts'); // i change mainbar part of it // i add/load data that i need in all those templates that are needed $data['view'] also my using same Array $data['my_required_data_that_i_use_in_template_files'] = 1; $this->load->view('main',$data); // } 

第三個在/ application / view文件夾中我有類似的結構

/view/main.php <-- which basically just determines which side's wrapper of web to load (frontend or backend or some other)

/view/frontend/wrapper.php

/view/backend/wrapper.php

/view/mobile/wrapper.php   <-- this wrappers are again another level of structuring for ex:

/view/backend/layouts/   <-- inside i have templates different layouts like 1column.php 2columns-left (have left side is narrow one),2columns-right,3columns... etc...

/view/backend/mainbar/   <-- inside i have templates for mainbar in pages

/view/backend/mainbar/.../ <-- in the same way it's possible to add folders for easily grouping templates for example for posts so you add for example

    /view/backend/mainbar/posts/  <-- all templates for creating, editing etc posts... 

    /view/backend/sidebar/   <-- inside i have templates for sidebar in pages

    /view/backend/...other special cases.... like dashboard.php

在/app/view/main.php文件看起來是這樣的:

if ($view['theend'] == "frontend")
{
$this->load->view('/frontend/wrapper');
} elseif ($view['theend'] == "backend")
{
$this->load->view('/backend/wrapper');
}

第五個包裝器是簡單的一些PHP在結構化的HTML中,你有頭(加載HTML標題,標題等...)標題/標題(如果有任何傳遞$ data ['view'] ['headers']變量加載在標題中/ array)布局(在布局文件中加載,只是具有下一級加載文件的新html結構化文件)頁腳/頁腳(如果有任何傳入的$ data ['view'] ['footers']變量,則在頁腳中加載)腳本(在標記之前加載分析/ facebook腳本等腳本)

第六,所以以同樣的方式,布局也將加載在public $ view = Array(....)中指定的mainbar / sidebar內容中

如果我需要某種方法,我只是覆蓋public $ view = Array(...)屬性的一部分,並且我只覆蓋不同的部分。

它完成了這樣的事情:

public function index()
{
    $data['view'] = $this->view;  // i take/load global class's attribute
    $data['view']['mainbar'] = Array('archive','related_posts'); // i change mainbar part of it
// i add/load data that i need in all those templates that are needed $data['view'] also my using same Array  $data['my_required_data_that_i_use_in_template_files'] = 1;
    $this->load->view('main',$data); //
}

最終加載如下:

  1. $這 - >負載>視圖( '主',$數據); < - 加載/app/view/main.php並傳遞$ data $ data有節點'view'($ data ['view']),其中有子節點確定其他重要的東西,比如:什么是結束什么布局,什么標題,什么頁腳等...

  2. 使用$ data ['view'] ['theend']中定義的數據,它會加載正確的包裝器

  3. 再次在包裝中使用$ data ['view'] ['layout']中的數據,它會加載其他更深層次的結構,如布局......
  4. 布局,使用相同的$ data ['view'] ['mainbar'],$ data ['view'] ['sidebar']並抓住其他重要部分加載,如主欄模板,側邊欄模板......

就是這個......

ps我很抱歉沒有使用數字,但stackoverflow系統是如此奇怪,而不是顯示3.它顯示我1 ..因為你看到我有一些嵌套列表...

我所做的(在Kohana 2中)有1個模板,包含所有子部分(如左側菜單,頂部標題),以及一個控制器,用於填充將在模板中替換的變量。

然后,每個子部分的變量可以由控制器本身調用的函數生成。 您還可以將這些函數放在單獨的控制器類的構造函數中,您的每個控制器都會擴展該控制器,以便它們自動運行並設置為類變量以便於訪問。

對於稍微好一點的模板,您可以將子部分放在單獨的文件中,大模板包含它們:

<?php include 'leftMenu.php'; ?>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM