使用视图(Using Views) ============================ 视图(Views)ä»£è¡¨çš„å°±æ˜¯ä½ åº”ç”¨ç¨‹åºçš„用户界é¢ã€‚视图通常由HTML文件嵌入PHP代ç 组æˆï¼Œè§†å›¾æä¾›äº†ä¸ºç”¨æˆ·è¯·æ±‚把数æ®è¾“出到æµè§ˆå™¨çš„任务。 :doc:`Phalcon\\Mvc\\View <../api/Phalcon_Mvc_View>` 负责管ç†MVC应用程åºä¸çš„视图层。 æœ¬ç»„ä»¶æ”¯æŒæ–‡ä»¶çš„层次结构,这个层次结构å…许常用的layout布局,以åŠä½¿ç”¨æŽ§åˆ¶å™¨å‘½å的文件夹å称,定义了å„自相应的视图模æ¿ã€‚ Integrating Views with Controllers ---------------------------------- Phalcon的视图组件会自动通过执行一个特定的控制器完æˆå®ƒçš„ç”Ÿå‘½å‘¨æœŸã€‚è§†å›¾ç»„ä»¶é¦–å…ˆè¦æ ¹æ®æœ€åŽçš„æŽ§åˆ¶å™¨å称找到视图文件目录, ç„¶åŽé€šè¿‡æœ€åŽçš„Action找到视图文件å,然åŽè¾“出视图内容。举例,如果一个URL请求是 *http://127.0.0.1/blog/posts/show/301* , Phalconä¼šè¿™æ ·è§£æžè¿™ä¸ªURL: +-------------------+-----------+ | Server Address | 127.0.0.1 | +-------------------+-----------+ | Phalcon Directory | blog | +-------------------+-----------+ | Controller | posts | +-------------------+-----------+ | Action | show | +-------------------+-----------+ | Parameter | 301 | +-------------------+-----------+ 分å‘器会寻找一个“PostsControllerâ€å’Œå®ƒçš„çš„Action “showActionâ€ã€‚一个简å•的控制器文件例å: .. code-block:: php <?php class PostsController extends \Phalcon\Mvc\Controller { public function indexAction() { } public function showAction($postId) { // Pass the $postId parameter to the view $this->view->setVar("postId", $postId); } } setVar方法å…许我们创建视图å˜é‡ï¼Œä»¥ä¾¿æˆ‘们å¯ä»¥åœ¨è§†å›¾æ–‡ä»¶ä¸ä½¿ç”¨å®ƒä»¬ã€‚上é¢çš„æ¼”示告诉我们如何把 $postId è¿™ä¸ªå‚æ•°ç»‘定到视图文件上。 :doc:`Phalcon\\Mvc\\View <../api/Phalcon_Mvc_View>` 使用PHP本身作为模æ¿å¼•æ“Žï¼Œå› æ¤æˆ‘们建议使用.phtml作为扩展å。如果视图目录是 *app/views* ,视图组件会自动找到以下3个视图文件。 +-------------------+-------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Name | File | Description | +===================+===============================+==========================================================================================================================================================================================================================+ | Action View | app/views/posts/show.phtml | This is the view related to the action. It only will be shown when the "show" action was executed. | +-------------------+-------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Controller Layout | app/views/layouts/posts.phtml | This is the view related to the controller. It only will be shown for every action executed within the controller "posts". All the code implemented in the layout will be reused for all the actions in this controller. | +-------------------+-------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Main Layout | app/views/index.phtml | This is main action it will be shown for every controller or action executed within the application. | +-------------------+-------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ ä½ å¹¶ä¸å¿…è¦ç¼–写上述æåˆ°çš„æ‰€æœ‰ä¸‰ä¸ªè§†å›¾æ–‡ä»¶ã€‚ :doc:`Phalcon\\Mvc\\View <../api/Phalcon_Mvc_View>` 会通过视图文件的层次自动查找下一层的视图文件。如果所有三个视图文件都å˜åœ¨ï¼Œä»–们将åšå¦‚下处ç†ï¼š .. code-block:: html+php <!-- app/views/posts/show.phtml --> <h3>This is show view!</h3> <p>I have received the parameter <?php $postId ?></p> .. code-block:: html+php <!-- app/views/layouts/posts.phtml --> <h2>This is the "posts" controller layout!</h2> <?php echo $this->getContent() ?> .. code-block:: html+php <!-- app/views/index.phtml --> <html> <head> <title>Example</title> </head> <body> <h1>This is main layout!</h1> <?php echo $this->getContent() ?> </body> </html> 请注æ„视图文件ä¸è°ƒç”¨ *$this->getContent()* 方法的那一行。这个方法的ä½ç½®å†³å®šå†…容在 :doc:`Phalcon\\Mvc\\View <../api/Phalcon_Mvc_View>` 的层次结构ä¸çš„上一个视图的哪个ä½ç½®æ˜¾ç¤ºã€‚上述示例将输出以下内容: .. figure:: ../_static/img/views-1.png :align: center 生æˆçš„HTML内容如下: .. code-block:: html+php <!-- app/views/index.phtml --> <html> <head> <title>Example</title> </head> <body> <h1>This is main layout!</h1> <!-- app/views/layouts/posts.phtml --> <h2>This is the "posts" controller layout!</h2> <!-- app/views/posts/show.phtml --> <h3>This is show view!</h3> <p>I have received the parameter 101</p> </body> </html> 使用模æ¿(Using Templates) --------------------------- Templates也是视图文件的一部分,但他们是å¯å…±äº«çš„ã€‚ä»–ä»¬ä½œä¸ºæŽ§åˆ¶å™¨çš„å¸ƒå±€æ–‡ä»¶ï¼Œä½ å¿…é¡»æŠŠå®ƒä»¬æ”¾åˆ°layouts目录下。 .. code-block:: php <?php class PostsController extends \Phalcon\Mvc\Controller { public function initialize() { $this->view->setTemplateAfter('common'); } public function lastAction() { $this->flash->notice("These are the latest posts"); } } .. code-block:: html+php <!-- app/views/index.phtml --> <!DOCTYPE html> <html> <head> <title>Blog's title</title> </head> <body> <?php echo $this->getContent() ?> </body> </html> .. code-block:: html+php <!-- app/views/layouts/common.phtml --> <ul class="menu"> <li><a href="/">Home</a></li> <li><a href="/articles">Articles</a></li> <li><a href="/contact">Contact us</a></li> </ul> <div class="content"><?php echo $this->getContent() ?></div> .. code-block:: html+php <!-- app/views/layouts/posts.phtml --> <h1>Blog Title</h1> <?php echo $this->getContent() ?> .. code-block:: html+php <!-- app/views/layouts/posts/last.phtml --> <article> <h2>This is a title</h2> <p>This is the post content</p> </article> <article> <h2>This is another title</h2> <p>This is another post content</p> </article> 最åŽå®ƒä»¬å°†è¾“出如下的HTML内容: .. code-block:: html+php <!-- app/views/index.phtml --> <!DOCTYPE html> <html> <head> <title>Blog's title</title> </head> <body> <!-- app/views/layouts/common.phtml --> <ul class="menu"> <li><a href="/">Home</a></li> <li><a href="/articles">Articles</a></li> <li><a href="/contact">Contact us</a></li> </ul> <div class="content"> <!-- app/views/layouts/posts.phtml --> <h1>Blog Title</h1> <!-- app/views/layouts/posts/last.phtml --> <article> <h2>This is a title</h2> <p>This is the post content</p> </article> <article> <h2>This is another title</h2> <p>This is another post content</p> </article> </div> </body> </html> Using Partials -------------- å±€éƒ¨æ¨¡æ¿æ–‡ä»¶æ˜¯å¦ä¸€ç§æ‰“ç ´è§†å›¾æ¸²æŸ“é¡ºåºçš„æ–¹å¼ï¼Œå®ƒæ›´æ˜“于管ç†ï¼Œä¸”å¯åœ¨åº”用程åºä¸é‡å¤ä½¿ç”¨ã€‚ 作为局部文件的方å¼ä¹‹ä¸€å¯ä»¥æŠŠå®ƒä»¬çœ‹ä½œæ˜¯å程åºï¼ŒæŠŠä½ 的视图代ç 分æˆå¤šä¸ªç»„æˆéƒ¨åˆ†ï¼Œæ›´å®¹æ˜“被ç†è§£ã€‚ä¾‹å¦‚ï¼Œä½ å¯èƒ½ä¼šæœ‰è¿™æ ·çš„æƒ³æ³•,看起æ¥åƒè¿™æ ·ï¼š .. code-block:: html+php <?php $this->partial("shared/ad_banner") ?> <h1>Robots</h1> <p>Check out our specials for robots:</p> ... <?php $this->partial("shared/footer") ?> Transfer values from the controller to views -------------------------------------------- :doc:`Phalcon\\Mvc\\View <../api/Phalcon_Mvc_View>` å¯ä»¥åœ¨æŽ§åˆ¶å™¨ä¸ä½¿ç”¨è§†å›¾å˜é‡($this->view)è°ƒç”¨ã€‚ä½ å¯ä»¥åœ¨æŽ§åˆ¶å™¨çš„Actionä¸ä½¿ç”¨è¯¥å¯¹è±¡çš„setVar()方法设置å˜é‡åˆ°è§†å›¾ä¸ã€‚ .. code-block:: php <?php class PostsController extends \Phalcon\Mvc\Controller { public function indexAction() { } public function showAction() { //Pass all the posts to the views $this->view->setVar("posts", Posts:find()); } } setView()çš„ç¬¬ä¸€ä¸ªå‚æ•°å称是将è¦åœ¨è§†å›¾æ–‡ä»¶ä¸ä½¿ç”¨çš„,å˜é‡å¯ä»¥æ˜¯ä»»æ„类型。从å—符串,整型数å—ï¼Œåˆ°ä¸€ä¸ªæ›´å¤æ‚的结构,如数组,集åˆç‰éƒ½å¯ä»¥ã€‚ .. code-block:: html+php <div class="post"> <?php foreach ($posts as $post) { echo "<h1>", $post->title, "</h1>"; } ?> </div> Control Rendering Levels ------------------------ 从以上å¯ä»¥çœ‹å‡ºï¼Œ:doc:`Phalcon\\Mvc\\View <../api/Phalcon_Mvc_View>` 支æŒè§†å›¾å±‚æ¬¡ç»“æž„ã€‚ä½ å¯èƒ½éœ€è¦åœ¨è§†å›¾ä¸æŽ§åˆ¶æ˜¾ç¤ºçš„层次,Phalcon\Mvc\\View::setRenderLevel() æä¾›è¿™ç§åŠŸèƒ½ã€‚ æ¤æ–¹æ³•å¯ä»¥ä»ŽæŽ§åˆ¶å™¨æˆ–ä»Žä¸Šçº§è§†å›¾å±‚è°ƒç”¨æ”¹å˜æ¸²æŸ“过程。 .. code-block:: php <?php class PostsController extends \Phalcon\Mvc\Controller { public function indexAction() { } public function findAction() { // This is an Ajax response so don't generate any kind of view $this->view->setRenderLevel(\Phalcon\Mvc\View::LEVEL_NO_RENDER); //... } public function showAction($postId) { // Shows only the view related to the action $this->view->setRenderLevel(\Phalcon\Mvc\View::LEVEL_ACTION_VIEW); } } The available render levels are: +-----------------------+--------------------------------------------------------------------------+ | Class Constant | Description | +=======================+==========================================================================+ | LEVEL_NO_RENDER | Indicates to avoid generating any kind of presentation. | +-----------------------+--------------------------------------------------------------------------+ | LEVEL_ACTION_VIEW | Generates the presentation to the view associated to the action. | +-----------------------+--------------------------------------------------------------------------+ | LEVEL_BEFORE_TEMPLATE | Generates presentation templates prior to the controller layout. | +-----------------------+--------------------------------------------------------------------------+ | LEVEL_LAYOUT | Generates the presentation to the controller layout. | +-----------------------+--------------------------------------------------------------------------+ | LEVEL_AFTER_TEMPLATE | Generates the presentation to the templates after the controller layout. | +-----------------------+--------------------------------------------------------------------------+ | LEVEL_MAIN_LAYOUT | Generates the presentation to the main layout. File views/index.phtml | +-----------------------+--------------------------------------------------------------------------+ Using models in the view layer ------------------------------ 应用程åºä¸çš„æ¨¡åž‹æ˜¯å¯ä»¥åœ¨è§†å›¾ä¸ç›´æŽ¥ä½¿ç”¨çš„ï¼Œå› ä¸º :doc:`Phalcon\\Loader <../api/Phalcon_Loader>` 在è¿è¡Œæ—¶ä¼šè‡ªåЍåˆå§‹åŒ–它们: .. code-block:: html+php <div class="categories"> <?php foreach (Catergories::find("status = 1") as $category) { echo "<span class='category'>", $category->name, "</span>"; } ?> </div> è™½ç„¶ä½ å¯ä»¥åœ¨è§†å›¾ä¸æ‰§è¡Œæ¨¡åž‹çš„å„ç§æ“作,如insert(),update()ç‰ï¼Œä½†ä¸å»ºè®®è¿™ä¹ˆä½¿ç”¨ã€‚å› ä¸ºå®ƒä¸å¯ä»¥åœ¨å‘生错误或异常的时候从一个控制æµç¨‹è·³è½¬åˆ°å¦ä¸€ä¸ªæŽ§åˆ¶å™¨ã€‚ Picking Views ------------- æ£å¦‚ä¸Šé¢æç¤ºçš„ï¼Œ:doc:`Phalcon\\Mvc\\Application <../api/Phalcon_Mvc_Application>` ç®¡ç† :doc:`Phalcon\\Mvc\\View <../api/Phalcon_Mvc_View>` è¿›è¡Œè§†å›¾æ˜¾ç¤ºï¼Œæ ¹æ®ç›¸å…³è”的最一个控制器和actionæ¥è¿›è¡Œè§†å›¾æ–‡ä»¶è¾“å‡ºã€‚ä½ ä¹Ÿå¯ä»¥é€šè¿‡ Phalcon\\Mvc\\View::pick() 方法改å˜è¿™ä¸ªæ˜¾ç¤ºæµç¨‹ï¼š .. code-block:: php <?php class ProductsController extends \Phalcon\Mvc\Controller { public function listAction() { // Pick "views-dir/products/search" as view to render $this->view->pick("products/search"); } } Caching View Fragments ---------------------- æœ‰æ—¶å€™ï¼Œå½“ä½ å¼€å‘动æ€ç½‘站时,网页上的有一些区域是ä¸ç»å¸¸æ›´æ–°çš„ï¼Œä»–ä»¬æ¯æ¬¡éƒ½è¾“出相åŒçš„内容。:doc:`Phalcon\\Mvc\\View <../api/Phalcon_Mvc_View>` æä¾›äº†ä¸€ç§ç¼“å˜åŠŸèƒ½ï¼Œå¯ä»¥å±€éƒ¨ç¼“å˜ï¼Œä¹Ÿå¯ä»¥ç¼“å˜æ•´ä¸ªé¡µé¢ï¼Œä»¥æé«˜æ€§èƒ½ã€‚ :doc:`Phalcon\\\Mvc\\View <../api/Phalcon_Mvc_View>` 集æˆäº† :doc:`Phalcon\\Cache <cache>` ,æä¾›äº†ä¸€ç§æ›´æ–¹ä¾¿çš„æ–¹æ³•æ¥è¿›è¡Œç¼“å˜æ“ä½œã€‚ä½ å¯ä»¥æ‰‹å·¥è®¾ç½®ç¼“å˜å¤„ç†ï¼Œæˆ–设置一个全局的缓å˜è§„则: .. code-block:: php <?php class PostsController extends \Phalcon\Mvc\Controller { public function showAction() { //Cache the view using the default settings $this->view->cache(true); } public function showArticleAction() { // Cache this view for 1 hour $this->view->cache(array( "lifetime" => 3600 )); } public function resumeAction() { //Cache this view for 1 day with the key "resume-cache" $this->view->cache( array( "lifetime" => 86400, "key" => "resume-cache", ) ); } public function downloadAction() { //Passing a custom service $this->view->cache( array( "service" => "myCache", "lifetime" => 86400, "key" => "resume-cache", ) ); } } 当我们没有为缓å˜å®šä¹‰ä¸€ä¸ªæ˜Žç¡®çš„KEY时,组件会自动创建一个针对视图文件åç§° md5_ çš„KEYã€‚è¿™æ ·å®šä¹‰KEYçš„æ–¹å¼æ˜¯éžå¸¸ä¸é”™çš„åšæ³•ï¼Œå› ä¸ºè¿™æ ·ä½ å°±å¯ä»¥å¾ˆå®¹æ˜“识别到æ¯ä¸ªAction与视图缓å˜çš„对应文件了。 当View组件需è¦ç¼“å˜ä¸€äº›å†…容的时候,它将从æœåŠ¡å®¹å™¨è¯·æ±‚cacheæœåŠ¡ã€‚ 这个æœåŠ¡åœ¨æœåС容噍ä¸çš„命å为"viewCache": .. code-block:: php <?php //Set the views cache service $di->set('viewCache', function(){ //Cache data for one day by default $frontCache = new Phalcon\Cache\Frontend\Output(array( "lifetime" => 86400 )); //Memcached connection settings $cache = new Phalcon\Cache\Backend\Memcached($frontCache, array( "host" => "localhost", "port" => "11211" )); return $cache; }, true); 当使用视图åŽï¼Œå¦‚果有缓å˜ï¼Œåº”直接输出缓å˜å†…å˜è¿›è¡Œæ˜¾ç¤ºï¼Œè€Œä¸è¦ä½¿æŽ§åˆ¶å™¨å†æ¬¡æ‰§è¡ŒèŽ·å–æ•°æ®ã€‚ ä¸ºäº†å®žçŽ°è¿™ä¸€ç›®æ ‡ï¼Œæˆ‘ä»¬å¿…é¡»ä½¿ç”¨å”¯ä¸€çš„ç¼“å˜KEY。首先,我们è¦å…ˆéªŒè¯ç¼“å˜çš„KEY是å¦å˜åœ¨æˆ–是å¦å·²è¿‡æœŸï¼Œæ•´ä¸ªè¿‡ç¨‹å¦‚下: .. code-block:: html+php <?php class DownloadController extends Phalcon\Mvc\Controller { public function indexAction() { //Check if the cache with key "downloads" exists or has expired if ($this->view->getCache()->exists('downloads')) { //Query the latest downloads $latest = Downloads::find(array('order' => 'created_at DESC')); $this->view->setVar('latest', $latest); } //Enable the cache with the same key "downloads" $this->view->cache(array('key' => 'downloads')); } } ç¦ç”¨è§†å›¾(Disabling the view) ------------------------------ 如果您的控制器ä¸äº§ç”Ÿä»»ä½•输出,您å¯ä»¥ç¦ç”¨è§†å›¾ç»„件,é¿å…ä¸å¿…è¦çš„处ç†ï¼š .. code-block:: php <?php class UsersController extends \Phalcon\Mvc\Controller { public function closeSessionAction() { //Disable the view $this->view->disable(); //The same $this->view->setRenderLevel(Phalcon\Mvc\View::LEVEL_NO_RENDER); } } 模æ¿å¼•擎(Template Engines) ---------------------------------- 模æ¿å¼•擎å¯å¸®åŠ©å‰ç«¯è®¾è®¡äººå‘˜æ— éœ€ä½¿ç”¨å¤æ‚çš„è¯æ³•å°±å¯ä»¥åˆ›å»ºè§†å›¾ã€‚Phalcon自身包å«äº†ä¸€ä¸ªå¼ºå¤§å¿«é€Ÿçš„æ¨¡æ¿å¼•擎 :doc:`Volt <volt>` 。 æ¤å¤–, :doc:`Phalcon\\Mvc\\View <../api/Phalcon_Mvc_View>` 还å…è®¸ä½ ä½¿ç”¨å…¶ä»–çš„æ¨¡æ¿å¼•擎替代PHP或Volt. 使用ä¸åŒçš„æ¨¡æ¿å¼•擎,通常需è¦å¤æ‚的外部PHPåº“ï¼Œç”¨äºŽè§£æžæ¨¡æ¿æ–‡ä»¶ã€‚è¿™é€šå¸¸ä¼šå¢žåŠ ä½ çš„åº”ç”¨ç¨‹åºçš„èµ„æºæ•°é‡ã€‚ å¦‚æžœä½ è¦ä½¿ç”¨ä¸€ä¸ªå¤–部模æ¿å¼•擎, :doc:`Phalcon\\Mvc\\View <../api/Phalcon_Mvc_View>` 会æä¾›å®Œå…¨ç›¸åŒçš„è§†å›¾å±‚æ¬¡ç»“æž„ï¼Œå®ƒåŒæ ·å¯ä»¥åœ¨æ¨¡æ¿ä¸è®¿é—®API。 该组件使用适é…器,这å¯ä»¥å¸®åŠ©å¤–éƒ¨æ¨¡æ¿å¼•擎在Phalcon䏿˜¯ç»Ÿä¸€çš„,让我们æ¥çœ‹çœ‹å¦‚何整åˆå…¶ä»–模æ¿å¼•擎的。 创建自己的模æ¿å¼•擎适é…器(Creating your own Template Engine Adapter) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 有很多的模æ¿å¼•擎,比如常用的Smartyï¼Œä½ å¯èƒ½éœ€è¦é›†æˆæˆ–自己创建一个。使用外部模æ¿å¼•擎的第一æ¥å°±æ˜¯è¦ä¸ºå®ƒåˆ›å»ºä¸€ä¸ªé€‚é…器。 模æ¿å¼•擎适é…器是一个类,它用作 :doc:`Phalcon\\Mvc\\View <../api/Phalcon_Mvc_View>` 与模æ¿å¼•擎集æˆå·¥ä½œçš„一个桥æ¢ã€‚通常åªéœ€è¦å®žçް __construct() å’Œ render() ä¸¤ä¸ªæ–¹æ³•ã€‚æž„é€ æ–¹æ³•ç”¨äºŽä¼ å…¥ :doc:`Phalcon\\Mvc\\View <../api/Phalcon_Mvc_View>` 的实际对象和æœåС容噍(DI). render()æ–¹æ³•æŽ¥æ”¶ä¸¤ä¸ªå‚æ•°ï¼Œç¬¬ä¸€ä¸ªä¸ºè§†å›¾æ–‡ä»¶çš„ç»å¯¹è·¯å¾„ï¼Œç¬¬äºŒä¸ªå‚æ•°æ˜¯é€šè¿‡ $this->view->setVar() 设置模æ¿å˜é‡ã€‚ .. code-block:: php <?php class MyTemplateAdapter extends \Phalcon\Mvc\View\Engine { /** * Adapter constructor * * @param \Phalcon\Mvc\View $view * @param \Phalcon\DI $di */ public function __construct($view, $di) { //Initiliaze here the adapter parent::__construct($view, $di); } /** * Renders a view using the template engine * * @param string $path * @param array $params */ public function render($path, $params) { // Access view $view = $this->_view; // Access options $options = $this->_options; //Render the view } } æ›´æ¢æ¨¡æ¿å¼•擎(Changing the Template Engine) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ä½ å¯ä»¥ä½¿ç”¨ä»¥ä¸‹æ–¹å¼åœ¨æŽ§åˆ¶å™¨ä¸æ›¿æ¢æˆ–æ·»åŠ ä¸€ä¸ªæ¨¡æ¿å¼•擎: .. code-block:: php <?php class PostsController extends \Phalcon\Mvc\Controller { public function indexAction() { // Set the engine $this->view->registerEngines( array( ".my-html" => "MyTemplateAdapter" ) ); } public function showAction() { // Using more than one template engine $this->view->registerEngines( array( ".my-html" => 'MyTemplateAdapter' ".phtml" => 'Phalcon\Mvc\View\Engine\Php' ) ); } } ä½ è¿˜å¯ä»¥å®Œå…¨æ›¿æ¢æ¨¡æ¿å¼•æ“Žï¼Œæˆ–åŒæ—¶ä½¿ç”¨å¤šä¸ªæ¨¡æ¿å¼•擎都是å¯ä»¥çš„。 \Phalcon\\Mvc\\View::registerEngines() æ–¹æ³•æŽ¥æ”¶ä¸€ä¸ªæ•°ç»„å‚æ•°ã€‚数组的KEY是扩展å,值为模æ¿å。扩展åç§°ä¸è¦ä¸€æ ·ï¼Œä»¥åŒºåˆ«ä½¿ç”¨çš„æ˜¯å“ªä¸ªæ¨¡æ¿å¼•擎。 如果使用多个模æ¿å¼•æ“Žï¼ŒåŒæ—¶è®¾ç½®çš„æ‰©å±•åç§°ä¸€æ ·ï¼Œé‚£ä¹ˆ :doc:`Phalcon\\Mvc\\View <../api/Phalcon_Mvc_View>` å°†åªæ˜¾ç¤ºç¬¬ä¸€ä¸ªã€‚ å¦‚æžœä½ æƒ³å®žçŽ°åœ¨åº”ç”¨ç¨‹åºä¸æ¯ä¸ªè¯·æ±‚都使用一个或一组模æ¿å¼•æ“Žï¼Œä½ å¯ä»¥æ³¨å†ŒviewæœåŠ¡åˆ°æœåŠ¡å®¹å™¨ï¼š .. code-block:: php <?php //Setting up the view component $di->set('view', function() { $view = new \Phalcon\Mvc\View(); $view->setViewsDir('../app/views/'); $view->registerEngines( array( ".my-html" => 'MyTemplateAdapter' ) ); return $view; }); 为了更好的ç†è§£å¦‚何创建一个模æ¿å¼•擎适é…器,让我们集æˆä¸¤ä¸ªä¼—所周知的模æ¿ï¼šMustache å’Œ Twig. Using Mustache ^^^^^^^^^^^^^^ `Mustache`_ 是一个logic-less的模æ¿å¼•擎,å¯ç”¨äºŽå¤šå¹³å°å¤šè¯è¨€ã€‚PHP的实现版本在这里 `this Github repository`_ 。 ä½ éœ€è¦åœ¨ä½¿ç”¨æ¨¡æ¿é€‚é…噍剿‰‹å·¥åŠ è½½Mustache的库文件。å¯ä»¥ä½¿ç”¨autoload的方å¼ï¼Œä¹Ÿå¯ä»¥ä½¿ç”¨includeåŒ…å«æ–‡ä»¶çš„æ–¹å¼ã€‚ .. code-block:: php <?php require "path/to/Mustache/Autoloader.php"; Mustache_Autoloader::register(); Mustache的适é…器看起æ¥åƒè¿™æ ·ï¼š .. code-block:: php <?php /** * Adapter to use Mustache library as templating engine */ class My_Mustache_Adapter extends \Phalcon\Mvc\View\Engine { protected $_mustache; protected $_params; public function __construct(Phalcon\Mvc\View $view, Phalcon\DI $di) { $this->_mustache = new Mustache_Engine(); parent::__construct($view, $di); } public function render($path, $params) { if (!isset($params['content'])) { $params['content'] = $this->_view->getContent(); } $this->_view->setContent($this->_mustache->render(file_get_contents($path), $params)); } } 现在,在控制ä¸ä½ éœ€è¦æŠŠæ¨¡æ¿å¼•æ“Žæ›¿æ¢æˆ Mustache 适é…å™¨ï¼Œå¦‚æžœä½ çš„æŽ§åˆ¶å™¨ä¸çš„æ‰€æœ‰Actionéƒ½ä½¿ç”¨æ¤æ¨¡æ¿å¼•æ“Žï¼Œä½ å¯ä»¥åœ¨initialize()æ–¹æ³•ä¸æ³¨å†Œå®ƒã€‚ .. code-block:: php <?php class PostsController extends \Phalcon\Mvc\Controller implements Phalcon\Mvc\View\EngineInterface { public function initialize() { // Changing PHP engine by Mustache $this->view->registerEngines( array(".mhtml" => "My_Mustache_Adapter") ); } public function showAction() { $this->view->setVar("showPost", true); $this->view->setVar("title", "some title"); $this->view->setVar("body", "a cool content"); } } ç›¸å¯¹çš„æ¨¡æ¿æ–‡ä»¶ (views-dir/posts/show.mhtml) 将使用 Mustache è¯æ³•进行解æžã€‚ .. code-block:: html+php {{#showPost}} <h1>{{title}}</h1> <p>{{body}}</p> {{/showPost}} æ¤å¤–,æ£å¦‚上é¢çœ‹åˆ°çš„ï¼Œä½ å¿…é¡»åœ¨è§†å›¾æ–‡ä»¶ä¸è°ƒç”¨æ–¹æ³• $this->getContent() 以包å«å†…容。在Moustacheä¸ï¼Œå®ƒæ˜¯è¿™ä¹ˆä½¿ç”¨çš„: .. code-block:: html+php <div class="some-menu"> <!-- the menu --> </div> <div class="some-main-content"> {{content}} </div> Using Twig ^^^^^^^^^^ Twig_ 是最近比较æµè¡Œçš„PHP模æ¿å¼•擎。 ä½ åœ¨ä½¿ç”¨æ¨¡æ¿å¼•擎适é…器å‰åŒæ ·éœ€è¦æ‰‹å·¥åŠ è½½Twig的库文件,使用autoloaderåŠ è½½å¯ä»¥æŒ‰å¦‚下方å¼å®žçŽ°ï¼š .. code-block:: php <?php require "path/to/Twig/Autoloader.php"; Twig_Autoloader::register(); Twig模æ¿å¼•擎适é…器看起æ¥åƒè¿™æ ·ï¼š .. code-block:: php <?php /** * Adapter to use Twig library as templating engine */ class My_Twig_Adapter extends \Phalcon\Mvc\View\Engine implements Phalcon\Mvc\View\EngineInterface { protected $_twig; public function __construct(Phalcon\Mvc\View $view, Phalcon\DI $di) { $loader = new Twig_Loader_Filesystem($view->getViewsDir()); $this->_twig = new Twig_Environment($loader); parent::__construct($view, $di); } public function render($path, $params) { $view = $this->_view; if (!isset($params['content'])) { $params['content'] = $view->getContent(); } if (!isset($params['view'])) { $params['view'] = $view; } $relativePath = str_replace($view->getViewsDir(), '', $path); $this->_view->setContent($this->_twig->render($relativePath, $params)); } } 从上é¢å¯ä»¥çœ‹å‡ºï¼Œä½ éœ€è¦æ›¿æ¢é»˜è®¤çš„æ¨¡æ¿å¼•擎或让它和其他的模æ¿å¼•擎一起工作。 .. code-block:: php <?php class PostsController extends \Phalcon\Mvc\Controller { public function initialize() { // Changing PHP engine by Twig $this->view->registerEngines( array(".twig" => "Twig") ); } public function showAction() { $this->view->setVar("showPost", true); $this->view->setVar("title", "some title"); $this->view->setVar("body", "a cool content"); } } åœ¨è¿™ç§æƒ…况下,相关的视图文件为views-dir/posts/show.twig,这个文件里é¢å†™çš„æ˜¯åŒ…å«twigè¯æ³•的代ç 。 .. code-block:: html+php {{% if showPost %}} <h1>{{ title }}</h1> <p>{{ body }}</p> {{% endif %}} ç„¶åŽéœ€è¦æŠŠå†…容包å«è¿›æ¥ï¼Œè¿™é‡Œä½¿ç”¨å˜é‡"content",å’ŒMustacheçš„æ–¹å¼æ˜¯ä¸€æ ·çš„: .. code-block:: html+php <div class="some-messages"> {{ content }} </div> Using Smarty ^^^^^^^^^^^^ Smarty_ 是å¦ä¸€ä¸ªPHP模æ¿å¼•擎,它负责应用逻辑和视图的分隔。 ä½ éœ€è¦åœ¨ä½¿ç”¨é€‚é…噍之剿‰‹å·¥åŠ è½½åº“æ–‡ä»¶ï¼Œè¿™ä¹ˆåšï¼š .. code-block:: php <?php require_once 'Smarty3/Smarty.class.php'; Smarty模æ¿å¼•擎适é…å™¨çœ‹èµ·æ¥æ˜¯è¿™ä¸ªæ ·å的: .. code-block:: php <?php class SmartyEngine extends \Phalcon\Mvc\View\Engine implements Phalcon\Mvc\View\EngineInterface { protected $_smarty; protected $_params; public function __construct(Phalcon\Mvc\View $view, Phalcon\DI $di) { $this->_smarty = new Smarty(); $this->_smarty->template_dir = '.'; $this->_smarty->compile_dir = SMARTY_DIR . 'templates_c'; $this->_smarty->config_dir = SMARTY_DIR . 'configs'; $this->_smarty->cache_dir = SMARTY_DIR . 'cache'; $this->_smarty->caching = false; $this->_smarty->debugging = true; parent::__construct($view, $di); } public function render($path, $params) { if (!isset($params['content'])) { $params['content'] = $this->_view->getContent(); } foreach($params as $key => $value){ $this->_smarty->assign($key, $value); } $this->_view->setContent($this->_smarty->fetch($path)); } } 在视图ä¸ä½¿ç”¨æœåŠ¡(Injecting services in View) ----------------------------------------------------------- æ¯ä¸ªè§†å›¾æ–‡ä»¶ä¸éƒ½åŒ…å« :doc:`Phalcon\\DI\\Injectable <../api/Phalcon_DI_Injectable>` 的实例对象,方便的æä¾›äº†è®¿é—®æœåŠ¡å®¹å™¨çš„åŠŸèƒ½ã€‚ 下é¢çš„例忼”示了如何在框架约定下写一个 jQuery `ajax request`_ 。视图文件ä¸åŒ…å«"url"这个æœåŠ¡ï¼Œä½ å¯ä»¥ç›´æŽ¥ä½¿ç”¨å®ƒï¼š .. code-block:: html+php <script type="text/javascript"> $.ajax({ url: "<?php echo $this->url->get("cities/get") ?>" }) .done(function() { alert("Done!"); }); </script> Stand-Alone Component --------------------- 在Phalconä¸ï¼Œä¸€èˆ¬ä½¿ç”¨ *glue* ç»„ä»¶ä½¿ä¸€äº›æ¾æ•£çš„组件连接在一起相互工作,形æˆä¸€ä¸ªfull-stack框架开å‘çŽ¯å¢ƒï¼Œä½†æ˜¯ä½ ä¹Ÿå¯ä»¥å•独使用 :doc:`Phalcon\\Mvc\\View <../api/Phalcon_Mvc_View>` : .. code-block:: php <?php $view = new \Phalcon\Mvc\View(); $view->setViewsDir("../app/views/"); // Passing variables to the views, these will be created as local variables $view->setVar("someProducts", $products); $view->setVar("someFeatureEnabled", true); //Start the output buffering $view->start(); //Render all the view hierarchy related to the view products/list.phtml $view->render("products", "list"); //Finish the output buffering $view->finish(); echo $view->getContent(); View Events ----------- :doc:`Phalcon\\Mvc\\View <../api/Phalcon_Mvc_View>` å¯ä»¥å°†äº‹ä»¶å‘é€åˆ° :doc:`EventsManager <events>` 。事件通过"view"æ¥è§¦å‘。一些返回布尔值false的事件å¯ä»¥è¢«åœæ¢ï¼Œæ”¯æŒä¸‹åˆ—一些事件: +----------------------+------------------------------------------------------------+---------------------+ | Event Name | Triggered | Can stop operation? | +======================+============================================================+=====================+ | beforeRender | Triggered before start the render process | Yes | +----------------------+------------------------------------------------------------+---------------------+ | beforeRenderView | Triggered before render an existing view | Yes | +----------------------+------------------------------------------------------------+---------------------+ | afterRenderView | Triggered after render an existing view | No | +----------------------+------------------------------------------------------------+---------------------+ | afterRender | Triggered after complete the render process | No | +----------------------+------------------------------------------------------------+---------------------+ 下é¢çš„示例演示如何将事件监å¬å™¨ç»‘定到组件: .. code-block:: php <?php $di->set('view', function() { //Create an event manager $eventsManager = new Phalcon\Events\Manager(); //Attach a listener for type "view" $eventsManager->attach("view", function($event, $view) { echo $event->getType(), ' - ', $view->getActiveRenderPath(), PHP_EOL; }); $view = new \Phalcon\Mvc\View(); $view->setViewsDir("../app/views/"); //Bind the eventsManager to the view component $view->setEventsManager($eventManagers); return $view; }); 下é¢çš„示例展示了如何创建一个æ’件,用æ¥clean/repair 在渲染过程ä¸çš„HTML代ç 。我们使用 Tidy_ æ¥æ¼”示: .. code-block:: php <?php class TidyPlugin { public function afterRender($event, $view) { $tidyConfig = array( 'clean' => true, 'output-xhtml' => true, 'show-body-only' => true, 'wrap' => 0, ); $tidy = tidy_parse_string($view->getContent(), $tidyConfig, 'UTF8'); $tidy->cleanRepair(); $view->setContent((string) $tidy); } } //Attach the plugin as a listener $eventsManager->attach("view:afterRender", new TidyPlugin()); .. _Mustache: https://github.com/bobthecow/mustache.php .. _Twig: http://twig.sensiolabs.org .. _this Github repository: https://github.com/bobthecow/mustache.php .. _ajax request: http://api.jquery.com/jQuery.ajax/ .. _Smarty: http://www.smarty.net/ .. _Tidy: http://www.php.net/manual/en/book.tidy.php .. _md5: http://php.net/manual/en/function.md5.php