cseufert/hamle

一个PHP模板引擎。HAMLE受到HAML/Jade的启发,但输入更少,且不允许在模板中写入PHP代码,但允许逻辑和函数调用。

v3.0.2 2024-04-18 00:12 UTC

README

Build Status codecov.io Scrutinizer Code Quality Maintainability

需要PHP >= 8.1

通过Composer安装

composer require cseufert/hamle dev-master

HAML的增强版本 - HAMLE

这个HAML移植使用略不同的语法与HAML标准格式。这里的主要想法是减少输入的符号数量。这个移植尝试解决的第二个问题是移除模板中的原生代码。这个想法是,你的模板可以作为HTML从服务器提供,然而,如果支持的话,它也可以由JavaScript渲染,通过一个小JSON请求来检索数据以填充模板。Hamle的主要关注点不是标记,而是页面/文档结构,所以内联标签在这个阶段不考虑。重点是干净、可读的标记。

  • CSS 类和ID,带或不带元素(例如 .myclassP.quoteA#home#content.cols.two
    • 如果没有指定HTML标签,则假定使用DIV
    • id和class的顺序没有特定要求,但是如果指定了名称,则必须首先指定
    • 多个ID(#one#two)将不被识别,只使用一个
    • 使用示例 #1 .one Text 变成 <div class="one">Text</div>
    • 使用示例 #2 span.two Foo 变成 <span class="two">Foo</span>
    • 使用示例 #3 #my.mine.ours 变成 <div id="my" class="mine ours"></div>
  • 缩进结构(类似Python),增加缩进意味着在父元素内部,减少缩进意味着关闭标签
html
  body
    div#content
      a[href=/] Home

变成

<html>
  <body>
    <div id="content">
      <a href="/">Home</a>
    </div>
  <body>
</html>
  • HTML标签直接写入,不需要符号(例如 DIVPA 等)
    • 在方括号中以url编码的字符串指定标签属性
    • 用 \& 转义 &,用 \] 转义 ] 等
    • 使用示例 #1 a[href=/] Home 输出 <a href="/">Home</a>
    • 使用示例 #2 .button[data-size=$id&class=$tags] 如果 $id 为 10 且 tags = 'Ten Submit' 输出将是 <button data-size="10" class="Ten Submit" />
    • 使用示例 #3 a[data-alt=Button \[1\&2\]] Hi 变成 <a data-alt="Button [1&amp;2]">Hi</a>
  • 所有变量替换都是PHP样式的,以$开头(例如 $title$text{$[-1]->title} 等)
    • 在HTML编辑器中的替代语法 {$[1]-!title}{$(page.home)-!title}
    • 在过滤器块内部或在访问属性时,需要使用 {$...} 而不是 $...
    • 作用域历史
      • $[0] = 当前作用域中的模型/控制器
        • 使用示例 #1 |with $[-1] - 切换回上一个作用域
        • 使用示例 #2 {$[1]->title} - 从初始作用域读取值 $title
      • $[-1] = 最后一个作用域;作用域数组 $[1] 是第一个作用域,$[-2] 是第二个最后的作用域
    • 命名作用域 (新特性)
      • 选择项目并分配名称,而不是使用数字作用域 |with $(page.footer) as footer
      • 现在要使用这个或它的变量,使用 $[footer]
      • 通过 |each $[footer] 遍历footer
      • 访问footer的HTML属性 {$[footer]->html}
    • 类似jQuery的魔术 $ 函数
      • $({}{@}{#}{.}{^}{:{-}})
        • <type> 是hamleSetup->modelType($type)可以找到的类型
        • <group> 是一个任意id,用于确定组类型,例如区分画廊图片和页眉图片
        • <id> 是一个唯一的标识符,可以是类型组合,也可以是全局唯一的。
        • <tags> 是用户定义的标签,可以用来帮助查找数据。
        • <sort> 字段用于排序,默认为升序,前缀为 - 表示降序,无前缀为随机。如果您想根据多个字段排序,例如按 sort 降序和 title 升序,则可以使用 ^-sort^title
        • <limit> 限制结果数量为 n。
        • <offset> 跳过的结果数量。
        • 唯一必需的字段是 <type><id>,具体取决于 modelFind 的实现。
      • $(#1024) 打开 id = 1024。
      • $(#mine) 打开具有 id/别名 = mine 的对象。
      • $(page#3) 打开 id = 3 的页面类型。
      • $(cat) 打开所有分类对象的列表。
      • $(product.onsale) 打开所有带有 onsale 标签的产品列表。
      • $(cart#summary) 打开购物车中的摘要项。
      • $(#mainmenu > page,cat) 返回 id = mainmenu 下所有类型为页面和 cats 的子项列表。
      • $( > photo, image) 返回当前作用域下所有子项为照片和图像的列表。
      • $( < cat) 返回当前作用域内类型为分类的所有父项。
      • $(page:1) 返回页面中的第一页。
      • $( > page,cat:3) 返回作用域内 3 个页面或 cats(总数)的子项。
      • $(news^postdate) 返回按 postdate 升序排序的所有新闻帖子。
      • $(news^-postdate) 返回按 postdate 降序排序的所有新闻帖子。
      • $(news^) 返回随机排序的所有新闻帖子。
      • $(news^-postdate^title) 返回按日期(降序)排序,然后按标题(升序)排序的所有新闻帖子。
      • $(link:5-10) 返回从 #5 到 10 的链接。
      • $(news:4) 返回 4 个新闻帖子。
      • $(product.featured:4^) 返回 4 个随机选择的具有 featured 标签的产品。
      • $(post:4^postdate) 返回按 postdate 排序的前 4 个博客帖子。
      • $(post^-postdate:1) 返回最新的博客帖子。
  • 可迭代的模型/控制器列表可以使用特殊方法。
    • |with $(#mainmenu > page) - 将 M/C 作用域更改为 mainmenu 下的页面,如果没有结果则跳过该部分。
    • |each - 遍历当前作用域(由 |with 设置)中的每个对象。
    • |each $(#social > icons) - 遍历来自 id = social 的子图标。
    • |include "block/$type/list.hamle" - 将另一个 hamle 文件引入文档,带有当前的 M/C 作用域。
      • 在文件名中激活变量替换。
    • |if $id equals $(view)->id - 如果此 id 是视图 id,则包含该部分。
      • if $title equals a
      • if $id notequal 54
      • if $tags has sale - 数组中有 sale。
      • if $title starts Hi
      • if $title ends s
      • if $title contains Hi - 包含字符串 Hi。
      • if $price greater 10
      • if $price less 10
    • |else - |with|if 的 else。
    • 未来想法
      • |page <key>,<size> <modelIterator> - 例如 |page results,16 $(#gallery > photo)
        • 特殊链接目标: a!firstpagea!prevpagea!nextpagea!lastpage;
        • 特殊页面功能:页面 div!thispagediv!pagecountdiv!pagelinks
      • |recurse $( > menu,page) #3 使用提供的表达式递归到 3 个级别深。
      • if $price less 10 OR $price greater 20
      • |unless $title - 如果不是快捷方式,如果标题不存在则显示块。
      • |switch $type - 根据 $type 切换。
        • |case page - 如果匹配案例,则包含部分。
        • |default - 如果没有案例匹配,则包含部分。
      • |iterateend - 迭代直到列表末尾。
        • |iterate 3 - 迭代 3 次。
        • 例如
  / Print a table with 3 column of all the products in the current scope (eg category)
  |with $( > products)
    table
      |iterateend
        tr
          |iterate 3
            td
              a[href=$url] $title
                |with $( > photo)
                  img[src=$url]
          |else
            td
  • 过滤器
    • :filtername - 使用名为 filtername 的过滤器处理部分)
    • 用法 #1 :javascript alert('Hi {$(user)->name}');
    • 用法 #2 :css a {color:{$(site)->linkcolor}}
    • 要在 CSS/JavaScript 等中使用 {$ 序列,只需转义美元符号,例如。{$
  • 注释
    • // 注释 - 不包含在输出中
    • / 注释 - 作为 HTML 注释包含
  • _ 这只是普通文本
    • 普通文本,可以轻松翻译
    • _ 仅在文本是新行的第一项时才需要
    • 要转义美元符号,请使用 $
    • 使用 '__' 当您不想转义任何 HTML 特殊字符(即,您想在输出中包含 HTML)时。
      • 例如 __ <!doctype html> 打印 HTML5 声明
      • 这也不会尝试解析任何变量(例如 {$title})
    • 使用 ___ 当您想要转义 HTML(包括变量)时。这允许将包含 HTML 的变量渲染为 HTML
  • 函数
    • {$title|strtoupper} 在模型的标题值上运行 strtoupper
    • {$amount|format_currency("$", $(#prefs)->places)} 向函数传递参数

示例

html
  body
    .head
      h1 This is my website
      img[src=/img/$imagename.png]
    .content
      .h2 $title
      |with $(#1012 > text)
        ul#mainmenu
          |each
            li.menuitem
              |if {$[1]->id} = $id
                a.highlight[href=$url] $title
              |else
                a[href=$url] $title
              |with $( > text)
                ul.submenu
                  |each
                    li.menuitem
                      |if {$[1]->id} = $id
                        a.highlight[href=$url] $title
                      |else
                        a[href=$url] $title
      .body
        |if $text
          $text
	    |else
          p Nothing to see here. Page ID=$id is emtpy
      .foot
        ul.socialicons
          |each $(#socialmedia > link)
            li.icon
               a[href=$url&class=$code]
                 img[alt=$title] $->child(“img”)->url
        |include "footer_$type.hamle"
        |if $alias != “home”
          a[href=/] Home
        .powered
          $(site)->poweredby

升级到版本 3.x

  • Hamle 构造函数不再需要模型,现在通过输出传递
  • 字符串现在在内存中运行,没有缓存文件
  • Runtime\Context 替换了 Hamle\Run 并包含了旧的 Hamle\Setup 方法
  • Runtime\Scope 现在是一个实例,不再通过静态方法访问