3.1 What is Smarty? / 什么是Smarty
Smarty 3 是一个Shopware前段的模板(template)工具。有了它,你不需要懂很多PHP的知识,只需要专注于HTML,CSS和JavaScript和一点点Smarty的知识就够了。
3.2 The basics / 基础知识
Smarty的语法和HTML,XML等标记语言很像。每个Smarty标签都以花括号 { 开始,以花括号 } 结束,就像HTML中的 <> 一样。包含Smarty的文件后缀名为 .tpl。 你可以把它当成一个包含了Smarty标签的HTML文档。
模板引擎(template engine)会渲染tpl文件并转换成有效的HTML文件形式。
举例:简单的Smarty标签
{s name="shopName"}DemoShop{/s}
{s}标签用于定义文本片段,并使他可翻译(make it translatable)。可以看到,Smarty标签都在花括号内,和HTML一样,它也可以有不同的属性比如这里的 name=""。
3.2.1 Variables
为了开始Smarty的学习,我们先尝试用Smarty输出从Shopware系统取得的信息。每个页面都由模板引擎进行渲染,并显示所需数据。所有数据都被存储在名为模板变量(template variables)。所有的变量都能通过Smarty的语法:美元符 $ + 变量名 调用到。
举例:变量输出
<h2>{$sArticle.name}</h2>
该例会输出变量.name的内容,输出样式为 h2。这里用到的分隔符 . 是用于访问其子值的(sub-values)。像本例中所看到的那样,变量可以不仅仅是简单的string或者number类型,它可以是一个数字集,即数组(array)。
上面的例子中,变量名为sArticle,该变量是个数组,包含了多个字段,而name是它字段中的一个。
模板变量可以被嵌套的更深,比如{$sArticle.image.thumbnails[0].source}。数组的所有字段可以通过 [] 语法访问到。
3.2.2 Modifiers
有时候我们不仅仅想要简单的输出变量内容,还想要在它被渲染之前对变量进行操作。这里我们就需要Smarty修饰符(Smarty modifiers)了。修饰符是一些用于修改变量输出的小函数。
举例:修饰符在变量上的应用
<div> {$sArticle.description|truncate:120} </div>
例子中,修饰符放在变量后面,通过简单的 | 符号 + 修饰符名字被使用。这里用到的truncate修饰符的作用是:将文本缩短到给定的字符数量,这里是120个字符,该参数通过:+ 数字使用。
你可以对一个变量同时使用多个修饰符,每个修饰符之间用 | 隔开即可。这些修饰符会按照书写顺序一个一个被用到。
举例:使用两个修饰符
比如,你想要在使用truncate方法指定字符串数之前,先把其中所包含的HTML标签去掉:
<div> {$sArticle.description|strip_tags|truncate:120} </div>
3.2.3 Conditions
有时候,你可能需要根据不同的条件输出不同的结果。这里条件语句用 {if} 标签,它包含了一条件判断,最后以 {/if} 结束。在这两个标签之间的内容只在条件判断为true时,才会被输出。
举例:定义一个条件
{if $sArticle.description} {$sArticle.description} {else} {$sArticle.description_long|strip_tags|truncate:120} {/if}
本例中,我们定义了一个简单的条件,来检测变量是否被定义。正如你所看到的,条件语句中包含了一个 {else} 标签,在条件不为真的情况下执行 {else} 标签之后的内容。更多的条件可以通过 {elseif} 来定义。如果想了解更多的操作符,请点击这里
3.2.4 Loops
为了能够处理更多数据,比如一个产品列表。我们可以通过循环(Loops)创造一个动态输出(dynamic output)。比如,我们可以通过迭代方法输出一个产品列表。
举例:数组循环
<ul> {foreach $sArticles as $item} <li>{$item.name}</li> {/foreach} </ul>
循环从 {foreach} 标签开始,到 {/foreach} 标签结束。在开始标签中,我们定义了一个想要迭代的数组($sArticles),以及在寻呼那种将要提供的单个数据集($item)。模板引擎会对 {foreach} {/foreach} 之间的每个item进行渲染,并且生成一个包含所有产品名的新列表。
**3.2.5 Official documentation / 官方文档
Smarty还有许多特性,但在这里不再赘述,如想要了解,请点击这里直接进入Smarty的官方文档。
3.3 Template inheritance / 模板继承
想要编辑Shopware中已存在的模板文档(template file),你不需要拷贝所有文件或重写核心代码。使用模板继承系统,你只需编辑真正想要更改的部分。 这有很多好处:
1. 不需要拷贝整个模板
2. 少些代码,少些维护
3. 你的模板一直可以升级(兼容性)
4. 你的模板仍然可以通过插件扩展
3.3.1 Inherit a standard theme / 继承默认主题
我们强烈推荐你在自定义主题时,使用模板继承系统。这样会为你省下很多时间和工作。Shopware提供了两个标准的主题供你选择。最常见的情况是使用Shopware Responsive主题。这是一个现代化,全响应式(fully responsiv)的主题,它实现了Shopware 5所有有趣强大的功能。你只需要做一些设计上的变更,而不需要重建shop的整个功能。如果你想要了解更多,并且从头开始构建自己的功能,你可以继承Shopware的Bare主题,该主题只继承了一些基础的HTML功能。
举例:在Theme.php中定义一个父主题
class Theme extends \Shopware\Components\Theme { protected $extend = 'Responsive'; // ... }
3.3.2 Inheritance and plugin templates / 模板继承和插件
在Shopware中安装的插件会被放在集成系统的特定位置中。
所有插件模板都放在核心主题模板(the templates of the core themes)后面。你可以通过设置Theme.php文档中的$injectBeforePlugins 变量来决定,你的主题是要在插件之前处理还是之后处理。
如果你想要创建一个可以在Shopware社区中被购买的普通主题,那么该变量值应为true,这样你的主题就会在插件之前被处理。-->这种方法保证了你可以在你的主题中使用所有插件。
如果你想在本地修改某个特定的插件,那么就把该变量设置为false,以扩展插件模板。
class Theme extends \Shopware\Components\Theme { protected $extend = 'Responsive'; protected $name = 'CustomTheme'; protected $injectBeforePlugins = true; // ... }
3.3.3 Overwriting template files / 重写模板文件
Shopware对所有前端文件都使用固定的文件路径结构,前端的每一个部分都有自己的路径和自己的模板文件。每个文件路径中你都可以找到index.tpl文件,它包括了该文件路径中的基础部分。
当你定义父主题时,你可以在自己的主题路径中创建一个同名的文件, 用于重写并覆盖已存在的模板文件(template files)。
比如,如果你想要完全重写 "产品细节" 页面,你可以在自定义的主题中,找到相对应的路径,比如 "产品细节" 页面对应的是 frontend/detail/index.tpl。
Shopware会移动检测到你创造的文件,并且将他们加入到模板继承系统中(template inheritance system)
3.3.4 Extending template files / 扩展模板
大多数情况下,你并不想要重写整个模板文件,只是想要编辑或修改其中的字部分。因此你需要用到Smarty的拓展方法 {extends}。该方法要写在文件的第一行,file属性的内容为你想要继承的文档路径。
举例:拓展一个模板文件
{extends file="parent:frontend/detail/index.tpl"}
在 {extends}
的 file=""
属性中,你定义的文档路径中,将默认主题文件夹(theme file)为根文件夹。
前缀parent:告诉Shopware在父主题中搜索文件。这样就能拓展父主题中的模板了。
被拓展的文件不能有自己的HTML结构,因为你必须自己告诉引擎,你的模板代码要放在哪里。相反,你将获得父文件定义的所有内容块。
注意:
{extends}
语句必须写在.tpl文档的第一行
3.3.5 Blocks / 代码块
Smarty代码块(blocks)被用来在逻辑段中构造模块代码(template code)。这些代码块可以被其他文件在特定的位置进行拓展。通过 {block}
标签我们可以在Smarty中创建代码块,该标签将代码内容作为一个新的段落(segment)封装起来。每个block都有 name=""
属性,给这段代码定义一个独一无二的名字。通过这个名字,我们能从其他文件中访问到这段代码。
举例:A.tpl中定义一个代码块
{block name="frontend_index_logo"}
<div class="logo--shop">
//...
</div>
{/block}
当你通过 {extends} 方法继承A.tpl这个模板文件时,就获得了访问该模板文件中所有blocks的能力,你可以这样访问这些blocks:
{* 使用方法一 *}
{block name="frontend_index_logo"}
{$smarty.block.parent}
<div class="shop--slogan">
<h2>My shop is the best!</h2>
</div>
{/block}
{* 使用方法二 *}
{block name="frontend_index_logo" append}
<div class="shop--slogan">
<h2>My shop is the best!</h2>
</div>
{/block}
使用方法一:
- 保留父代码块(parent block)的内容 ==>
{$smarty.block.parent}
- 在
frontend_index_logo
这个Block中,加上了自己的代码 ==><div class="shop--slogan"> ... </div>
使用方法二:
append
这个修饰符在原Block之后添加<div class="shop--slogan"> ... </div>
。
其他修饰符还有:
- append:在parent template {block}之后添加内容
- prepend:在parent template {block}之前添加内容
- hide:如果该Block没有子Block,则该Block将被忽视
- nocache:该Block禁用缓存
总结一下,如果你需要编辑或者修改继承的模块,需要这样操作:
- 在模板文件中找到你想要修改的block
- 在你自己的theme下,按照同样的路径创建同名的模板文件
- 在2中创建的模板文件中添加 {extend} 标签,并且在file属性中写上1中找到的文件路径
- 在3中新建的模板文件中定义block。你可以通过将 {$smarty.block.parent} 写在自定义内容的前面/后面,来决定自定义内容和原block内容的先后顺序。
3.4 Register custom smarty plugins / 注册自定义Smarty插件
Shopware 5中,我们添加了在自定义theme中使用自定义插件的功能。用户能够创建新的修饰符和Smarty功能。要注册一个新的插件,你需要在你的主题中创建相关的文件路径结构。详细教程请点击这里
举例:自定义Smarty插件的路径
/_private/smarty/function.markdown.php /_private/smarty/modifier.picture.php