A Guide to Using Template
正在尋找如何安裝Template的文件嗎?請查閱 【開始】。 或是從【介紹Template】了解更多有關於這個類別庫
使用者指南主題
I. 設定
Template擁有自訂的設定檔 template.php,這個檔案應該被放置在一個包含有config.php, database.php, autoload.php等等…的 config 目錄夾內
使用你慣用的編輯器開啟 config/template.php 並設定它,和大部分其它的CodeIgniter設定檔一樣,所有的設定選項被配置在一個一維陣列裡, 此外我們也設定了一個名為 $template 的變數,允許你像 config/database.php 那樣定義變數群組,好讓你可以在你的應用程式上交替多種樣版
設定預設樣版
Template 要求你至少要定義一個變數群組來當做預設的主樣版
$template['active_group'] = 'default';
$template['default']['template'] = 'template.php';
$template['default']['template'] 表示你在 views 目錄夾中預設主樣版的檔案名稱。典型的樣版檔案內容將包含你預先定義區塊的 HTML 或 XML 結構 。詳細的檔案結構將會大概 像這樣.
注意: 若指定的樣版檔案不存在於 views 目錄中,Template將會出現錯誤。你可以從 views 目錄夾為起啟點,使用內部相對路徑指定到你的樣版檔案,例如 $template['default']['template'] = 'myview/template.php'Template將會試著去搜尋 views/myview/template.php 這個檔案
定義區塊
什麼是區塊(regions)? 區塊是指樣版中某個將會被置放內容的位置。他被定義在一個簡單易懂的陣列原型['regions']。 你也許可以在區塊變數裡置放一些預設的markup、 包覆標籤和屬性等(不建議),或是簡單的定義你想使用的區塊變數
一個簡單的區塊陣列變數:
$template['default']['regions'] = array(
'header',
'content',
'footer',
);
變數 $header, $content, 和 $footer 區塊將會透過你的應用程式被寫入到主樣版指定的位置
注意: 陣列的索引文字('header')將會被自動轉為區塊變數('$header')名稱所以必需注意不得有空白、破折號等
如果你需要的話,也可以將區塊變數轉為混合索引陣列,來設定包含預設的內容、包覆標籤、 markup等。下列為可能用到的索引
| Index | Instructions |
|---|---|
| content | 必需為陣列! 用來設定預設的區塊內容 |
| name | 一個用來識別區塊的字串名稱,他將被定義在索引值中 |
| wrapper | 一個用來包覆區塊內容的HTML標籤 (我們不建議你這樣使用,這個動作應該交給樣版去完成,而不是區塊) |
| attributes | 定義包覆標籤中的多重屬性陣列 (我們不建議你這樣使用,這個動作應該交給樣版去完成,而不是區塊) |
範例:
$template['default']['regions'] = array(
'header' => array(
'content' => array('<h1>Welcome</h1>','<p>Hello World</p>'),
'name' => 'Page Header',
'wrapper' => '<div>',
'attributes' => array('id' => 'header', 'class' => 'clearfix')
)
);
最後在區塊在樣版輸出的結果將為: <div id="header" class="clearfix"><h1>Welcome</h1><p>Hello World</p></div>
定義樣版剖析器
Template 將預設使用 CodeIgniter 的樣版剖析器類別來擴充為自己的樣版剖析器,設定與你樣版對應的['parser'] 和 ['parser_method'] 群組變數:
$template['default']['parser'] = 'smarty_parser';
// Template 將會呼叫 smarty_parser::parse()
$template['default']['parser'] = 'frog_parser';
$template['default']['parser_method'] = 'frog';
// Template 將會呼叫 frog_parser::frog()
['parser'] 為你在 application/libraries 目錄中,用來剖析的自訂類別庫名稱, 必要時你可以透過['parser_method']指定剖析器預設呼叫的的函式(當剖析類別的函式不是常規的"parse()"時)
最後, 將 ['parse_template'] 變數設為 TRUE 讓 Template 自動使用剖析器來重繪樣版:
$template['default']['parse_template'] = TRUE;
你可以在任何時間透過應用程改變指定剖析的類別和函式。查閱 使用樣版剖析器 這個章節來了解更多的資訊
II. 建立主樣版
讓我們從建立主樣版開始來使用Template吧。假設我們已完成大概95%想像中的基本架構如下:
Fig. 1 A simple two-column design with a header and a footer
以這個設計為基礎,我們可以來定義一些每頁都有可能不一樣內容的區塊位置。讓我們先來修改 config/template.php 設定檔中的區塊陣列變數
$template['default']['regions'] = array(
'header',
'title',
'content',
'sidebar',
'footer',
);
不過看起來我們的 header 和 footer 區塊似乎每頁都有相同的內容。雖然保持這兩個區塊可以保有樣版的彈性,但是我們可以從我們的設定檔為這兩個區塊添加或覆蓋預設的內容。我們將加入下列兩行到 config/template.php 的設定檔中
$template['default']['regions']['header'] = array('content' => array('<h1>CI Rocks!</h1>'));
$template['default']['regions']['footer'] = array('content' => array('<p id="copyright">© Our Company Inc.</p>'));
完畢! 我們已完成所有設定。讓我們編寫 views/template.php 中的主樣版檔吧! 將各區塊變數配置到樣版中適當的位置:(基於簡潔的理由,這個範例將被簡化HTML結樣,並且使用php短標籤"<?=")
就這樣! 現在,我們將要了解如何透過應用程式中的控制類去使用樣版和區塊
III. 寫入區塊
我們可以開始從我們控制類來配置寫入定義的區塊。但首先,讓我們來瞧瞧如何輸出最後完成的樣版
$this->template->render($region = NULL, $buffer = FALSE, $parse = FALSE)
This is the method that, by default, outputs our rendered template to the browser or other client. This method should be the last thing called from any public Controller methods that make use of the Template Libary.
To only render a specific region's contents, pass the region name in the first parameter. When a valid region name is supplied, render() will always only return the rendered string, and parsing does not apply.
$title = $this->template->render('title');
echo $title;
To store an entire rendered template in a variable without outputing it to the client, pass TRUE in the second argument:
$this->template->set_template('email');
$email_message = $this->template->render('', TRUE);
$this->email->message($email_message);
$this->email->send();
The third $parse argument instructs Template to either use the defined parser class or Views when rendering the regions. See Using Template Parsers for more information.
Let's start with a basic controller called 'page' that, by default, renders our template as is by only calling $this->template->render():
現在,當我們使用瀏覽器開啟時將會開見:
Fig. 2 Our template is loaded with only default content appearing.
正如你所見的, content, title 和 sidebar 區塊內容是空的,因為我們還沒寫入任何內容到這個區塊位置,而且我們也沒在 config/template.php 設定檔中,預設這些區塊的內容。另外,我們的HTML驗證器或許會顯示錯誤提示,因為我們 <h2> tag where $title should be. Let's take care of that.
$this->template->write($region, $content, $overwrite = FALSE)
Template 的 write() 函式是將一個內容追加寫入到區塊最基本的方法。 它將使用最少的參數:
- $region: 一段我們希望寫入的區塊的名稱字串
- $content: 一段我們希望寫入的內容字串
函式 write() 會把若使用同區塊名稱 $region 的內容 $content 追加到已存在的內容後面,但我們也可以透過給予第三個變數TRUE來覆蓋先前的內容
$this->template->write('content', 'You one ');
$this->template->write('content', 'bad mother...');
// $content region = "You one bad mother..." ($content內容從後面追加)
$this->template->write('content', "Shut'yo mouth!", TRUE);
// $content region = "Shut'yo mouth!"($content先前的內容被覆蓋了)
$this->template->write_view($region, $view_file, $view_data, $overwrite = FALSE)
使用 write() 函式可以讓我們讀取一個視圖的結果到變數後,並將他寫到我們的樣版中。 但是 Template 提供了一個 write_view() 函式來加速程序和節省每次單行單行的寫法
如同 write() 一樣, write_view() 第一個參數為我們將寫入的區塊名稱,第一個參數,我們將傳入一個視圖的檔案名稱(不包含".php"副檔名),並且選擇性的各別給予視圖一個資料陣列,如同典型使用CI $this->load->view() 函式一樣。同樣地,如果我們希望覆蓋先前的已存在的內容,我們給予第四個變數TRUE
$data = array('name' => 'John Smith', 'birthdate' => '11/15/1950');
$this->template->write_view('content', 'user/profile', $data, TRUE);
/* Template loads the views/user/profile.php view with the $data array passed in
and writes the result to the $content region, overwriting any previous content in the region */
讓我們來使用兩個函式來完成寫入資料到樣版:
現在,我們從瀏覽器讀取我們控制類指定的頁面,我們可以看完成的網頁:
Fig. 3 Avoiding messy code and calling views from within views,
we've filled out our template with just a few calls to Template methods in our Page controller.
Cascading Views
基於Template 類別庫的彈性原則, so the write_view() method lets you suggest other View files to load if the defualt View file you passed in the first argument doesn't exist. To suggest other View files for Template to use, pass them discretely, starting with the 5th argument:
$data['posts'] = $this->blog->get_recent(5);
$this->template->write_view('content', 'blog/front', $data, FALSE, 'blog/posts');
If this was a blog application, using this method lets us create a View file at views/blog/front.php to format blog posts distinctly when they appear on the front page, or opt-out and let our standard views/blog/posts.php handle the output. We could suggest more fallbacks if needed in the 6th, 7th, 8th arguments, and so on.
What happens if I write to a region that I hadn't previously defined?
Template will show an error if you attempt to write to a region that was not previously defined in the config file or otherwise. See how to manipulate templates and template regions in the following section, "Dynamically Manipulating Template."
"My template uses other variables that aren't necessarily regions. How do I supply those within Template?"
You most likely will use variables in your main template that aren't content regions. For example, you might have a $body_id variable that you apply to the <body> element that you use in your CSS to apply styles to specific pages. This certainly could be a region, but it wouldn't quite fit the metaphor.
To supply these variables to your master template, use CodeIgniter's $this->load->vars() mechanism.
Note: Unfortunately, I do not believe the $this->load->vars() function works for most or any parsers. Creating regions for these variables or using the Config class might be the only viable solutions.
IV. 動態處理樣版
The whole idea of Template is to improve the interface between your application's business logic and presentational markup by providing a very flexible wrapper to CI's Views implementation. Consider an application that required two or more markedly different templates for different pages or sections (like a blog with a main HTML template and RSS feed template). Or, consider if a plugin architecture was to allow for making components available to all your pages (like a User plugin that provides a login form). Rather than limiting it to using the regions defined in your configuration, a plugin should be able to dynamically provide its own regions for writing. These methods allow for these and other development scenarios.
$this->template->set_template($group)
The set_template() method is how you switch between different template groups defined in your config/template.php file. Template will throw an error if you attempt to set a template group not previously defined or dynamically added.
$this->template->set_template('rss');
// Template will now use the master template and regions from the $template['rss'] group
Tip: Use this method in Controller constructors where the entire Controller uses a separate template.
$this->template->add_template($group, $template, $switch)
Not all templates must be defined in config/template.php. The add_template() method allows templates to be dynamically added, and you can pass TRUE as a third parameter to switch to the added template.
$rss['template'] = 'rss.php';
$rss['regions'] = array('name', 'items');
$this->template->add_template('rss', $rss, TRUE);
// Template will now use the master template and regions from the supplied $rss template group
configuration
- $group is the handle that would be needed if this template was later invoked by the set_template() method
- $template is the properly formed template group configuration array, defining the master template and available regions
- $switch can be set to TRUE to automatically invoke this new template group settings
$this->template->set_master_template($filename)
In some cases you might only want to change the master template file of the current template configuration. This is useful for when multiple templates must share common regions and parser settings.
To swap the master template, call set_master_template() with the desired path and filename of the new master template:
$theme = 'lovely_butterflies';
$this->template->set_master_template('themes/'. $theme .'/template.php');
Template will now render the template file located at application/views/themes/lovely_butterfiles/template.php
The ".php" extension is not necessarily required. Template will use the EXT constant if one is not supplied.
$this->template->add_region($name, $settings = array())
The add_region() method allows one to dynamically add regions for writing. At a minimum, a $name must be supplied to identify the region. Optionally, a $settings array can be passed in to provide default content, wrappers and attributes.
$this->template->add_region('user_login');
$this->template->write_view('user_login', 'user/login_block');
如果區塊變數 $name 已經存在,Template 將會拋出一個例外錯誤
V. 使用樣版剖析器
In addition to interfacing with Views, Template provides a standard way to use template parsers when writing data to regions or rendering your master template. Although Template uses CodeIgniter's Template Parser class by default, one can provide any parser or engine (like Smarty) for Template to use.
$this->template->parse_view($region, $view_file, $view_data, $overwrite = FALSE)
To use CodeIgniter's Template Parser class, or an alternative parser like Smarty, to parse a View, use the parse_view() method. parse_view() works identically to write_view(), so you can also discretely suggest other Views to parse, starting with the 5th argument.
$data = array(
'blog_title' => 'My Blog Title',
'blog_heading' => 'My Blog Heading'
);
$this->template->parse_view('content', 'blog_template', $data);
如何添加剖析器
方法 1: 從 config/template.php 設定檔指定
你可加入不同的群組變數設定檔, 告知template將使用哪個剖析類別。Template將試去使用從 ['parser'] 指定類別去呼叫 ['parser_method'] 函式,若函式不存在,則呼叫預設的parse()函式
$template['default']['parser'] = 'smarty_parser';
// Template will call smarty_parser::parse()
$template['default']['parser'] = 'frog_parser';
$template['default']['parser_method'] = 'frog';
// Template will call frog_parser::frog()
方法 2: 動態指定使用剖析的類別
二選一, 你可以透過 set_parser() 函式動態的指定你要使用的剖析類別
$this->template->set_parser('smarty_parser');
// Template will call smarty_parser::parse()
$this->template->set_parser('frog_parser', 'frog');
// Template will call frog_parser::frog()
剖析類別的結構
A parser class is simply a CodeIgniter Library that provides a method which parses a given template file with the supplied data and returns its output. Let's write our own very simple parser class to see how it works:
We'll save this file as a library at application/libraries/Lame_parser.php. As you can see, a parser class' parser method will be passed $template, the template file to be parsed, and $data, an array of key/value pairs used in parsing the given template's pseudo code. Also note that a parser method should ALWAYS return the result of the parsed template and not echo it. Template will always supply a 3rd argument as TRUE to instruct some parser methods to do this by default.
Now, let's configure a template to use our lame parser:
$tpl = array(
'template' => 'lame_template.php'
);
$this->template->add_template('lame', $tpl, TRUE);
$this->template->add_region('content');
$this->template->set_parser('lame_parser');
$this->template->parse_view('content', 'templates/lamer', array('stuff' => 'things'));
echo $this->template->render('content'); // Just render the 'content' region
Running the above results in This parser is lame. Obviously a parser is actually going do more, but this shows the process: The returned value of Lame_parser::parse() is written to our 'content' region.
使用Smarty Template 做為剖析器
大部分的人不使用CI的樣版剖析器,而想要使用較受歡迎的Smarty Template。幸運地CI社群已經提供一個Smarty_parser類別 library that fits right in to Template's parser interface. 下面為快速指引你如何開始使用Smarty Template:
- Follow the directions for installing the Smarty_parser library found here: Yet Another Smarty Thread
- Configure your template group to use the Smarty_parser library:
$template['default']['template'] = 'template.tpl';
$template['default']['regions'] = array('header', 'content', 'footer');
$template['default']['parser'] = 'smarty_parser';
$template['default']['parse_template'] = TRUE;
就這樣! 現在Template當parse_view()函式是空的話,會改用Smarty_parser類別,你的主樣版將會被正常的剖析
NOTE: There is no guarantee that the third-party Smarty_parser library will work 100% as advertised. Please raise issues in the appropriate CodeIgniter forum threads.
剖析主樣版
如果你希望Template以parse()的方法,去剖析視圖後套用重繪,有三種方法可以讓你指定Template去剖析樣版
- 在 config/template.php 設定檔中,設定必要的樣版群組變數 ['parse_template']
為 TRUE
$template['default']['parse_template'] = TRUE; - 動態指令設定類別屬性 parse_template 為 TRUE,接著進行套用重繪
$this->template->parse_template = TRUE;
$this->template->render(); - 當呼叫 render() 時給予第三個參數 ,記得要給予前面兩個參數適當的忽略值
$this->template->render(NULL, FALSE, TRUE);
VI. 附加的實用函式
CSS定義了你HTML的風格,有些特效動態效果必需依靠JavaScript,所以不外乎Template也提供下列的函式來幫助你載入指定的相關資源
$this->template->add_js($script, $type = 'import', $defer = FALSE)
- $script: 依照 $type 參數的不同,傳入以$config['base_path']為基礎的檔案路徑字串(包含副檔名) 或欲嵌入的Javascript程式碼
- $type: 有兩種模式 'import' 或 'embed' 可選用,使用 'import' 為從外部載入指定的JavaScript檔案,使用 'embed' 為將Javascript式碼以<script> 包覆後嵌入
- $defer: 設定 TRUE 會在script中追加 defer="defer" 屬性
//載入外部js程式碼
$this->template->add_js('js/jquery.js');
//嵌入alert('Hello')程式碼到網頁中
$this->template->add_js('alert("Hello!");', 'embed');
你必需在你的樣版中,定義一個名稱為 $_scripts 區塊變數(而且盡量是放在<head>裡面),Template將會將產生的Javascript結果配置到此變數
$this->template->add_css($style, $type = 'link', $media = FALSE)
- $style: 依照 $type 參數的不同,傳入以$config['base_path']為基礎的檔案路徑字串(包含副檔名) 或欲嵌入的CSS程式碼
- $type: 有三種模式 'link', 'import' 或 'embed' 可選用,使用 'link' 為從外部載入指定的CSS檔案,使用 'import' 為以 @import 方式載入指定的CSS檔案,使用 'embed' 為將CSS程式碼以<style> 包覆後嵌入
- $media: 設定CSS顯示的媒介,可選用有 'all', 'screen', 'print', 'handheld',等…
$this->template->add_css('css/main.css');
$this->template->add_css('#logo {display: block}', 'embed', 'print');
你必需在你的樣版中,定義一個名稱為 $_styles 區塊變數(而且盡量是放在<head>裡面),Template將會將產生的CSS結果配置到此變數
注意: 函式 add_css() 和 add_js() 不會去檢查路徑的實體檔案是否存在,請記得確實指定以$config['base_path']為基礎的有效相對路徑位置。 另外如果提供的 $type 參數是無效的話,將會回傳 FALSE
更多的實用函式,像是設定 META 標籤,語系描述,以及其它典型會在HEAD被設定的實數參數。將會在未來的版本被加入。當然如果你等不及的話 。你可以自將函式行改你所需的函模式