Components
Introduction
组件是可配置的构建元素,可以附加到任何页面、部分或布局。组件是 Winter 的主要功能。每个组件都实现了一些扩展您网站的功能。组件可以在页面上输出 HTML 标记,但这不是必需的 - 组件的其他重要功能正在处理AJAX 请求、表单回发和页面执行周期(用于向页面注入变量或返回自定义响应)。
本文介绍组件基础知识,不解释如何使用使用 AJAX 的组件 或者开发组件 作为插件的一部分。
NOTE: 在 partials 中使用组件的功能有限,这在动态Partials 文章。
Introduction
如果您使用后端用户界面,您可以通过单击“组件”面板中的组件将组件添加到您的页面、部分和布局。如果您使用文本编辑器,您可以通过将其名称添加到页面或布局来将组件附加到页面或布局Configuration 模板文件的一部分。下一个示例演示如何将演示待办事项组件添加到页面:
title = "Components demonstration"
url = "/components"
[demoTodo]
maxItems = 20
==
...
这将使用组件部分中定义的属性初始化组件。许多组件都有属性,但这不是必需的。有些属性是必需的,有些属性有默认值。如果您不确定组件支持哪些属性,请参考开发者提供的文档,或者使用 Winter 后端的 Inspector。单击页面或布局组件面板中的组件时,检查器将打开。
当您引用一个组件时,它会自动创建一个与组件名称匹配的页面变量(demoTodo
在前面的例子中)。提供 HTML 标记的组件可以在页面上呈现{% component %}
标签,像这样:
{% component 'demoTodo' %}
NOTE: 如果将同名的两个组件一起分配给页面和布局,则页面组件会覆盖布局组件的任何属性。
组件别名
如果有两个插件使用相同的名称注册组件,您可以通过使用其完全限定的类名并为其分配一个组件来附加一个组件alias:
[Winter\Demo\Components\Todo demoTodoAlias]
maxItems = 20
该部分中的第一个参数是类名,第二个是附加到页面时将使用的组件别名。如果您指定了一个组件别名,那么当您引用该组件时,您应该在页面代码中的任何地方使用它。请注意,下一个示例引用了组件别名:
{% component 'demoTodoAlias' %}
别名还允许您通过先使用短名称然后使用别名来在同一页面上定义同一类的多个组件。这使您可以在页面上使用同一组件的多个实例。
[demoTodo todoA]
maxItems = 10
[demoTodo todoB]
maxItems = 20
使用外部属性值
默认情况下,属性值在定义组件的 Configuration 部分进行初始化,并且属性值是静态的,如下所示:
[demoTodo]
maxItems = 20
==
...
然而,有一种方法可以使用从外部参数加载的值来初始化属性 - URL 参数或partial 参数(对于在 partials 中定义的组件)。使用{{ paramName }}
应从部分变量加载的值的语法:
[demoTodo]
maxItems = {{ maxItems }}
==
...
假设在上面的例子中组件demoTodo 在部分中定义,它将使用从中加载的值进行初始化maxItems 部分变量:
{% partial 'my-todo-partial' maxItems='10' %}
您可以使用点表示法从外部参数中检索深度嵌套的值:
[demoTodo]
maxItems = {{ data.maxItems }}
==
...
要从 URL 参数加载属性值,请使用{{ :paramName }}
语法,名称以冒号 (:
), 例如:
[demoTodo]
maxItems = {{ :maxItems }}
==
...
页面,组件所属,应该有对应的网址参数 定义:
url = "/todo/:maxItems"
在 Winter 后端,您可以使用 Inspector 工具为组件属性分配外部值。在 Inspector 中,您不需要使用大括号来输入参数名称。 Inspector 中的每个字段在右侧都有一个图标,用于打开外部参数名称编辑器。输入参数名称为paramName
对于部分变量或:paramName
对于 URL 参数。
将变量传递给组件
组件可以设计为在渲染时使用变量,类似于部分变量,它们可以在组件名称之后指定{% component %}
标签。指定的变量将显式覆盖组件属性, 包括外部属性值.
在这个例子中,maxItems 组件的属性将设置为7 在渲染组件时:
{% component 'demoTodoAlias' maxItems='7' %}
NOTE: 并非所有组件都支持在渲染时传递变量。
自定义默认标记
组件提供的标记通常用作组件的使用示例。在某些情况下,您可能希望修改组件的外观和输出。将默认标记移动到主题部分 适用于彻底检修一个部件。覆盖组件部分 可用于樱桃采摘区自定义。
将默认标记移动到部分
每个组件都可以有一个入口点 partial 调用default.htm 当{% component %}
标记被调用,在下面的例子中我们假设组件被调用blogPost.
url = "blog/post"
[blogPost]
==
{% component "blogPost" %}
输出将从插件目录呈现components/blogpost/default.htm.您可以从此文件复制所有标记并将其直接粘贴到页面中或粘贴到新的部分,称为blog-post.htm 例如。
<h1>{{ __SELF__.post.title }}</h1>
<p>{{ __SELF__.post.description }}</p>
在标记内,您可能会注意到对名为的变量的引用__SELF__
, this 指的是组件对象,应替换为页面上使用的组件别名,在本例中为blogPost
.
<h1>{{ blogPost.post.title }}</h1>
<p>{{ blogPost.post.description }}</p>
这是允许默认组件标记在主题内的任何地方工作所需的唯一更改。现在可以使用主题部分自定义和呈现组件标记。
{% partial 'blog-post.htm' %}
对于在组件部分目录中找到的所有其他部分,可以重复此过程。
覆盖组件部分
可以使用主题部分覆盖所有组件部分。如果一个组件调用channel 使用title.htm 部分的。
url = "mypage"
[channel]
==
{% component "channel" %}
我们可以通过在我们的主题中创建一个名为partials/channel/title.htm.
文件路径段分解如下:
Segment | Description |
---|---|
partials |
主题部分目录 |
channel |
组件别名(部分子目录) |
title.htm |
要覆盖的部分组件 |
通过简单地为组件分配同名的别名,可以将部分子目录名称自定义为任何内容。例如,通过分配channel 具有不同别名的组件foobar 覆盖目录也发生了变化:
[channel foobar]
==
{% component "foobar" %}
现在我们可以覆盖title.htm 通过在我们的主题中创建一个名为partials/foobar/title.htm.
“查看包”组件
Winter 中包含一个特殊组件,称为viewBag
可以在任何页面或布局上使用。它允许在标记区域内轻松地定义和访问临时属性作为变量。一个很好的用法示例是在页面内定义一个活动菜单项:
title = "About"
url = "/about.html"
layout = "default"
[viewBag]
activeMenu = "about"
==
<p>Page content...</p>
然后使用viewBag
多变的。例如,在这个布局中active 如果类被添加到列表项viewBag.activeMenu
值设置为about:
description = "Default layout"
==
[...]
<!-- Main navigation -->
<ul>
<li class="{{ viewBag.activeMenu == 'about' ? 'active' }}">About</li>
[...]
</ul>
NOTE: viewBag 组件隐藏在后端,仅可用于基于文件的编辑。它也可以被其他插件用来存储数据。
软元件
软组件是主题中的组件,即使链接的组件不再可用,它们也会继续运行。这允许主题和网站开发人员在他们的主题中指定可选的插件组件,如果插件和/或组件存在,这些组件将提供特定的功能,同时允许网站在组件不再存在时继续运行。
当页面上存在软组件并且该组件不可用时,不会为该组件生成任何输出。
您可以通过在组件名称前加上前缀来定义软组件@
象征。
url = "mypage"
[@channel]
==
{% component "channel" %}
在这个例子中,应该channel
组件不可用,{% component "channel" %}
呈现页面时将忽略标记。
软组件也可以使用别名:
url = "mypage"
[@channel channelSection]
==
{% component "channelSection" %}
由于软组件不包含组件不可用时组件可能正常提供的任何数据,因此您必须注意确保任何自定义标记都能妥善处理任何缺失的组件信息。例如:
url = "mypage"
[@channel]
==
{% if channel.name %}
<div class="channel">
{% channel.name %}
</div>
{% endif %}