视图
视图是 MVC 中的 V。 视图负责为请求生成指定的输出。常用的格式有 HTML、XML 或者 JSON,不过用户可以下载的流文件和 PDF 文件也可以由视图层提供。
Cake
- 可以使用 JSON 和 XML 视图. 建立 XML 或者 JSON webservices
- 可以使用 媒体视图 提供受保护的文件,或者动态生成文件
- 可以使用 主题 生成多主题视图
视图模板
Cake
Cake
视图存储在 /app/View/ ,所有文件都放在以控制器命名的子文件夹中,文件名则是以动作命名的。例如,Products 控制器的 “view()” 动作的视图通常是 /app/View/Products/view.ctp。
Cake
- views:视图是动作运行的唯一的页面部分。它们构成了应用程序的响应。
- elements:小的可重用的视图代码。元件通常在视图内部渲染。
- layouts: 应用程序中打包了呈献逻辑的一些视图接口文件。多数视图在布局内部渲染。
- helpers:这些类包装了视图层的许多地方都使用的视图逻辑。除了其它事项,Cake
继承视图
2.1 新版功能.
视图继承允许你在一个视图中包含另一个视图。使用 视图块 进行绑定提供了保持视图 DRY 的强劲手段。例如,应用程序中有一个边栏,它在特定的视图中需要呈献不同的内容。通过继承一个共用的视图文件,你无需重复边栏中共有的标记,只需要定义改变的部分:
1 // app/View/Common/view.ctp 2 $this->fetch('title'); ?>
3 $this->fetch('content'); ?> 4 5 ="actions"> 6
Related actions
7
8 $this->fetch('sidebar'); ?> 9
10
上面的视图文件可以作为父视图。它需要继承它的视图定义 sidebar 和 title 块。它将包含继承视图中所有未捕获的内容。假设我们的视图文件有一个带有帖子数据的 $posts 变量,我们的视图看起来将是这个样子的:
1 2 // app/View/Posts/view.ctp 3 $this->extend('/Common/view'); 4 5 $this->assign('title', $post); 6 7 $this->start('sidebar'); 8 ?> 9
10 11 echo $this->Html->link('edit', array( 12 'action' => 'edit', 13 $post['Post']['id'] 14 )); ?> 15 16 $this->end(); ?> 17 18 // 剩余的内容将以父视图中的 'content' 块的形式生效 19 h($post['Post']['body']);
上面显示的这个帖子视图展示了如何继承一个视图,并且植入一个块集。块中未定义的内容将被捕捉并放入一个叫做content 的特殊块。当一个视图包含一个 extend() 调用,其将一直执行到当前文件的结尾。一旦它完成,被继承的视图被渲染。一个视图调用 extend() 超过一次, 将用后一个父视图覆盖前一个父视图:
1 $this->extend('/Common/view'); 2 $this->extend('/Common/index');
上面的代码中, `` /Common/index.ctp`` 将作为当前视图的父视图。
必要时,你可以嵌套继承视图。如果需要,每个视图都能被另一个视图继承。每个父视图将获得前一个视图的内容,当作自己的 content 块。
注解
你应该在应用程序中避免使用 content 作为块名。Cake
使用视图块
2.1 新版功能.
视图块放在 $scripts_for_layout,并提供一个允许你在视图/布局中任意位置定义插槽或者块的灵活的 API。 块是实现类似边栏这样的东东的理想方法,或者是在布局的头/尾加载资源的好地方。块有两种定义方式:作为捕获块,或者通过直接赋值。start()、 append() 和 end() 方法是和捕获块一同工作的:
1 // 建立一个边栏块 2 $this->start('sidebar'); 3 echo $this->element('sidebar/recent_topics'); 4 echo $this->element('sidebar/recent_comments'); 5 $this->end(); 6 7 8 // 随后添加一个边栏 9 $this->append('sidebar'); 10 echo $this->element('sidebar/popular_topics'); 11 $this->end();
也可以多次使用 start() 添加进一个块。 任何时候都可以使用 assign() 清除或者覆盖一个块:
1 // 清除之前定义的边栏块的内容。 2 $this->assign('sidebar', '');
在 2.3 版本中,新加了几个与块一同工作的方法。prepend() 预置一个已存在的块的内容:
1 // 预置到边栏。 2 $this->prepend('sidebar', 'this content goes on top of sidebar');
startIfEmpty() 方法在一个块为空或者未定义时生成一个块。如果块已经存在,则 startIfEmpty() 定义的内容被忽略。当你想要在块不存在时为其定义默认内容时,可以使用这一方法::
1 // 在视图文件中。 2 // 创建一个导航栏块。 3 $this->startIfEmpty('navbar'); 4 echo $this->element('navbar'); 5 echo $this->element('notifications'); 6 $this->end(); 7 8 // 在父视图/布局中。 9 $this->startIfEmpty('navbar'); 10 Default content 11 $this->end(); 12 13 echo $this->fetch('navbar');
上面的例子中,navbar 块包含在第一部分中添加的内容。一旦在子视图中定义了这个块,其默认内容将被忽略。
注解
应该避免使用 content 作块名。它被用于 Cake
显示块
2.1 新版功能.
可以使用 fetch() 方法显示块。 fetch 将安全地输出一个块,如果块不存在,就返回 ‘’。
1 echo $this->fetch('sidebar');
还可以根据一个块是否存在来决定是否显示其内容。要想在布局、继承视图文件中有条件的显示头或者其它标签时,这种方法非常有用:
1 // 在 app/View/Layouts/default.ctp 中 2 ($this->fetch('menu')): ?> 3 ="menu"> 4
Menu options
5 $this->fetch('menu'); ?> 6 7 ; ?>
在 2.3.0 版,还可以在块没有内容时为其提供默认值。这使为空状态添加占位符变得更容易。可以使用两个参数提供默认值:
1 ="shopping-cart"> 2
Your Cart
3 $this->fetch('cart', 'Your cart is empty'); 4
在 2.3 版更改: $default 添加于 2.3 版。
使用 script 和 CSS 文件块
2.1 新版功能.
块替代了被废弃的 $scripts_for_layout 布局变量。HtmlHelper 关联到视图块,它的 script() 、 css() 和 meta()方法在与 inline = false 选项共同使用时使用相同的相同的名字更新一个块。
1 2 // 在视图文件中。 3 $this->Html->script('carousel', array('inline' => false)); 4 $this->Html->css('carousel', null, array('inline' => false)); 5 ?> 6 7 // 在布局文件中。 8 9
注解
在 2.1 版之前,fetch() 方法无效。fetch('content') 是 2.0 版中 $scripts+for_layout 变量里包含的$content_for_layout 和 fetch('meta')、fetch('css')、fetch('script') 行的替代品。
script、 css 和 meta 块包含所有使用内置 HTML 助手定义在定义在视图中的内容。用于包含来自视图的 javascript 和 CSS 文件。
注解
当在视图文件中使用 HtmlHelper::css() 或 HtmlHelper::script() 时,将 ‘inline’ 设置为 ‘false’,将在一个带有相同名字的块中放置 html 源代码。(更多的详细信息和用法请参见 API)
content 块包含渲染视图的内容。
$title_for_layout 包含页面标题。这个变量是自动生成的,不过你能够通过在控制器/视图中设置它的值来覆盖其自动生成的默认值。
要设置布局的标题,最简单的办法是在控制器中设置 $title_for_layout 变量:
1 class UsersController extends AppController { 2 public function view_active() { 3 $this->set('title_for_layout', 'View Active Users'); 4 } 5 }
也可以在视图文件中设置 title_for_layout 变量:
1 $this->set('title_for_layout', $titleContent);
可以根据自己的愿望建立许多布局:把它们放进 app/View/Layouts 目录, 然后在控制器动作中使用控制器或者视图的$layout 属性在不同布局间切换:
1 // 通过控制器的布局属性 2 public function admin_view() { 3 // stuff 4 $this->layout = 'admin'; 5 } 6 7 // 通过视图的布局属性 8 $this->layout = 'loggedin';
举例来说,假设我的站点包含一个小的广告条,我可能会创建一个带有小型广告空间的新布局,并把它指定为所有的控制器方案都使用的一部分:
1 class UsersController extends AppController { 2 public function view_active() { 3 $this->set('title_for_layout', 'View Active Users'); 4 $this->layout = 'default_small_ad'; 5 } 6 7 public function view_image() { 8 $this->layout = 'image'; 9 //output user image 10 } 11 }
除了 CakeController::flash() 方法显示消息。
内核中的另外三个视图,xml,js 和 rss,是提供非 text/html 内容的简捷方法。
使用插件中的布局
2.1 新版功能.
如果你想使用插件中的布局,可以用 插件语法。 例如,使用 Contacts 插件中的 contact 布局:
1 class UsersController extends AppController { 2 public function view_active() { 3 $this->layout = 'Contacts.contact'; 4 } 5 }
元素
很多应用程序都有需要在多个页面重复使用的处理显示的代码块,有时是在布局的不同地方。 Cake元素。广告、帮助、导航控制、扩展菜单、登录表单和标注,在 Cake
元素放在 /app/View/Elements/ 文件夹,使用 .ctp 作为文件扩展名。 在视图中使用 element 方法输出元素:
1 echo $this->element('helpbox');
向元素传递变量
可以通过 element 方法的第二个参数向元素传递数据:
1 echo $this->element('helpbox', array( 2 "helptext" => "Oh, this text is very helpful." 3 ));
在元素文件中,所有传递过来的变量被当作参数数组的成员变量(与和视图文件一起工作的控制器中的Controller::set() 方法设置的变量相同)。在上例中, /app/View/Elements/helpbox.ctp 文件可以使用 $helptext变量:
1 // 在 app/View/Elements/helpbox.ctp 中 2 echo $helptext; //输出 "Oh, this text is very helpful."
View::element() 方法也支持元素的选项。这些选项支持 ‘缓存’ 和 ‘回调’。例如:
1 echo $this->element('helpbox', array( 2 "helptext" => "This is passed to the element as $helptext", 3 "foobar" => "This is passed to the element as $foobar", 4 ), 5 array( 6 "cache" => "long_view", // 使用 "long_view" 缓存配置 7 "callbacks" => true // 将此元素的 before/afterRender 回调设置为 true 8 ) 9 );
元素缓存很容易通过 Cache 类实现。可以让元素以你设置的任何缓存配置进行存储。 这为你决定在哪儿和如何长期存储元素提供了极为灵活地方法。 为达到在应用程序中缓存同一元素的不同版本的目的,可以通过使用如下格式为每个版本提供一个唯一的缓存键的方式:
1 $this->element('helpbox', array(), array( 2 "cache" => array('config' => 'short', 'key' => 'unique value') 3 ) 4 );
可以通过使用 requestAction() 来获得元素的全部优点。 requestAction() 函数从控制器动作中获取视图变量,并以数组形式返回它们。 这会使你的元素能够以真正的 MVC 风格运行。 建立一个为元素准备视图数据的控制器动作,然后在 element() 的第二个参数中调用 requestAction(),自控制器向元素提供视图变量。
要做到这一点,在控制器中加入类似于下面的 Post 例子中的内容:
1 class PostsController extends AppController { 2 // ... 3 public function index() { 4 $posts = $this->paginate(); 5 if ($this->request->is('requested')) { 6 return $posts; 7 } else { 8 $this->set('posts', $posts); 9 } 10 } 11 }
然后我们就能够通过元素访问分页的 posts 模型。我们可以通过如下方式获取最后五个帖子的有序列表:
1 Latest Posts
2 $posts = $this->requestAction('posts/index/sort:created/direction:asc/limit:5'); ?> 3 4 ($posts as $post): ?> 5 - $post['Post']['title']; ?>
6 ; ?> 7
缓存元素
如果你提供了缓存参数,你就可以获得 CakeCache 的更多信息参见 缓存 。一个简单的缓存元素的例子:
1 echo $this->element('helpbox', array(), array('cache' => true));
如果你在一个视图中多次渲染了同一元素,只要确保每次手忙脚乱的 ‘key’ 参数的值是不同的即可。这将防止连续的调用会覆盖前一个元素调用的缓存结果。例如:
1 echo $this->element( 2 'helpbox', 3 array('var' => $var), 4 array('cache' => array('key' => 'first_use', 'config' => 'view_long') 5 ); 6 7 echo $this->element( 8 'helpbox', 9 array('var' => $differenVar), 10 array('cache' => array('key' => 'second_use', 'config' => 'view_long') 11 );
上面的例子保证了两个元素的缓存结果是相互隔离的。 如果你想所有的元素缓存使用同一个缓存配置,你可以通过设置 View::$elementCache 给你想使用的缓存配置的方式来保存一些重复项。在什么都不提供时,Cake
从插件请求元素
2.0
要从插件载入元素,使用 plugin 选项(从 1.x 版的 data 选项中移出):
1 echo $this->element('helpbox', array(), array('plugin' => 'Contacts'));
2.1
如果你使用了一个插件并且希望使用其内置的元素,使用熟知的 插件语法。 如果视图被插件 控制器/动作 渲染,插件的名字将自动添加到所有要用的元素的前面,直到另一个插件名称出现。 如果插件内不存在这个元素,将会在主 APP 文件夹内寻找它:
1 echo $this->element('Contacts.helpbox');
如果视图是插件的一部分,你可以活略插件名。例如,如果你在 Contacts 插件的 ContactsController 中工作:
1 echo $this->element('helpbox'); 2 // 和 3 echo $this->element('Contacts.helpbox');
是等同的,其结果是渲染了同一个元素。
在 2.1 版更改: $options[plugin] 选项被废弃,同时添加了 Plugin.element 支持。
建立你自己的视图类
你可能需要建立自定义的新数据视图类型的视图类,或者向应用程序添加附加的自定义视图渲染逻辑。就像多数 Cake
- 视图文件要放在 App/View``文件夹中。例如 ``App/View/PdfView. 。
- 视图文件必须以 View 做后缀。例如 PdfView 。
- 在指定要渲染的视图类名时,需要省略 View 后缀。例如 $this->viewClass = 'Pdf'; 。
你也许需要扩展 View 以使某些东西正常工作:
1 // 在 App/View/PdfView. 2 3 App::uses('View', 'View'); 4 class PdfView extends View { 5 public function render($view = null, $layout = null) { 6 // custom logic here. 7 } 8 }
替换 render 方法会让你对如果渲染内容有更大的控制权。
View API
class View
视图方法在所有的视图、元素和布局文件中都可用。
使用 $this->method() 调用视图方法。
View::set(
string $var,
mixed $value)
视图有一个与控制器对象中的 set() 方法作用相同的 set() 方法。在视图文件中调用 set() 方法将向附后被渲染的布局或元素中添加变量。关于使用 set() 方法的更多信息参见 控制器方法 。
可以在视图文件中使用:
1 $this->set('activeMenuButton', 'posts');
之后 $activeMenuButton 变量就可以在布局中使用了,并且它的值为 ‘posts’ 。
View::getVar(string $var)获取视图变量 $var 的值
View::getVars()获取当前渲染范围内的所有有效的视图变量的列表。返回变量名组成的数组。
View::element(string $elementPath, array $data, array $options = array())渲染元素或者局部视图。更多的信息和示例参见 元素 一节。
View::uuid(string $object, mixed $url)为对象生成基于对象类型和 url 的唯一的非随机的 DOM ID。这个方法常常被助手使用,为每个元素生成唯一的 DOM ID,例如 JsHelper:
1 $uuid = $this->uuid('form', array('controller' => 'posts', 'action' => 'index')); 2 //$uuid 包含 'form0425fe3bad'
View::addScript(string $name, string $content)向内部脚本缓冲添加内容。这个缓冲在布局中是 $scripts_for_layout。当用手需要直接向布局添加 javascript 或者 css 时很有用。 谨记,从布局或者布局中的元素中添加的脚本不能补添加到 $scripts_for_layout。 此方法经常用在助手中,比如 Javascript 助手 和 Html助手 助手。
2.1 版后已移除: 被 使用视图块 特性取代。
View::blocks()获取所有已定义的块的名字,返回结果为所有名字构成的数组。
View::start($name)开始捕获视图块。参见 使用视图块 一节的示例。
2.1 新版功能.
View::end()结束最近开放的捕捉块。参见 使用视图块 一节的示例。
2.1 新版功能.
View::append($name, $content)以 $name 为名称向块中追加内容。参见 使用视图块 一节的示例。
2.1 新版功能.
View::prepend($name, $content)以 $name 为名称向块中预存内容。 参见 使用视图块 一节的示例。
2.3 新版功能.
View::startIfEmpty($name)在块为空时开始一个块。如果块已经被定义,则其全部内容将被捕获并抛弃。
2.3 新版功能.
View::assign($name, $content)为块赋值。这会覆盖已存在的内容。参见 使用视图块 一节的示例。
2.1 新版功能.
View::fetch($name)获取块的值。如果块没有定义,其值为’‘(空字符串)。 参见 使用视图块 一节的示例。
2.1 新版功能.
View::extend($name)继承以 $name 命名的 视图/元素/布局。参见 使用视图块 一节的示例。
2.1 新版功能.
property View::$layout设置包含当前视图的布局。
property View::$elementCache这个缓存配置用于缓存元素。设置此属性将改变默认的元素缓存配置。 此默认值可以使用 element 方法的 ‘cache’ 选项覆盖。
property View::$requestCakeRequest 的实例。使用此实例方法有关当前请求的信息。
property View::$output包含最后渲染的视图内容(来自视图文件或者布局内容)。
2.1 版后已移除: 被 $view->Blocks->get('content'); 代替。
property View::$BlocksViewBlock 的实例。用于在视图渲染中提供视图块功能。
2.1 新版功能.
关于视图的更多内容
- 主题
- 媒体视图
- JSON 和 XML 视图
- 在应用程序中允许使用数据视图
- 利用 serialize 键使用数据视图
- 利用视图文件使用数据视图
- 助手
- 使用和配置助手
- 使用助手
- 回调方法
- 创建助手
- 为所有助手创建功能
- 助手 API
- 内核 Helpers
02-01 06:06