讀 Slim 框架代碼(3)

View

Slim 框架提供了一個 View Engine (\Slim\View 類),在使用的時候經過 $app->render('myTemplate.php', array('id' => $id)); 的方法能夠把模板轉換成頁面。還能夠自定義 View Engine,只須要繼承 \Slim\View 類,並實現其 render() 方法,並在建立 \Slim\Slim 類實例的時候經過 settings 指定自定義的 View:php

$app = new \Slim\Slim(array(
    'view' => new CustomView()
));

默認 View

In slim.phpgit

public function render($template, $data = array(), $status = null)
{
    if (!is_null($status)) {
        $this->response->status($status); 
    }
    $this->view->setTemplatesDirectory($this->config('templates.path'));
    $this->view->appendData($data);
    $this->view->display($template);
}

在執行 $app->render('myTemplate.php', array('id' => $id)) 的時候,會依次執行 View 的 setTemplatesDirectoryappendDatadisplay 方法。github

setTemplatesDirectory 設置模板的目錄,默認是 ./templates 目錄。數組

\Slim\View 類有個 data 成員變量,是一個 \Slim\Helper\Set 類,這個類是對關聯數組的一個封裝,在關聯數組的基礎上提供了一些自定以的方法。appendData 會把調用 render 函數時傳進來的關聯數組的鍵值對寫到這個成員變量中。緩存

In View.phpapp

public function appendData($data)
{
    if (!is_array($data)) {
        throw new \InvalidArgumentException('Cannot append view data. Expected array argument.');
    }
    $this->data->replace($data);
}
...
public function replace($items)
{
    foreach ($items as $key => $value) {
        $this->set($key, $value); // Ensure keys are normalized
    }
}
...
public function set($key, $value)
{
    $this->data[$this->normalizeKey($key)] = $value;
}

最後的 display 方法通過 \Slim\Viewfetch 方法的的結果打印出來,而 fetch 方法直接調用了 render 方法。這也是爲何自定義的 View 類要實現 render 方法。框架

In View.php函數

protected function render($template)
{
    $templatePathname = $this->getTemplatePathname($template);
    if (!is_file($templatePathname)) {
        throw new \RuntimeException("View cannot render `$template` because the template does not exist");
    }
    extract($this->data->all());
    ob_start();
    require $templatePathname;

    return ob_get_clean();
}

extract 會把關聯數組的鍵值對抽成變量和對應的值(extract 方法)。而後 ob_start 開啓緩存捕獲輸出,這樣在模板中的 echo $var 之類的輸出會被捕獲成字符串,最後隨着模板一塊兒返回。這樣就實現了變量的替換。fetch

自定義 View

自定義的 View 渲染過程和默認的 View 同樣,只是經過實現 render 方法有更靈活的使用場景,好比能夠給用自定義的 View 來實現其餘框架的 layout 功能(實例1實例2)。ui

相關文章
相關標籤/搜索