Download the PHP package migears/yaml-pages without Composer

On this page you can find all versions of the php package migears/yaml-pages. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package yaml-pages

migears/yaml-pages

Version

A declarative YAML page definition tool that compiles .page.yaml declarations into miGears Template files (.tpl.php), which the template engine then compiles to pure PHP on first render. The YAML declaration is the single source of truth; generated templates are derived artifacts and must not be hand-edited.

Background: miGears is the open-source successor of TinyGears, a self-developed PHP framework. It was renamed and open-sourced recently because the name TinyGears is already taken in the open-source community.

Features

Boundaries

In scope

Not in scope (by design)

How It Works

Two deliberate compilations:

  1. yaml-pages parses the YAML declaration into the array DSL of migears/pages; the shared compiler there turns it into .tpl.php sugar syntax (## $expr ##). The intermediate output stays readable, so each DSL keyword maps visibly to template syntax.
  2. migears/template's TemplateCompiler turns that sugar into a pure PHP template (mtime-cached, recompiled only when the template changes). Rendering is plain PHP: the template runs and its variables are output to the browser as HTML. The declaration layer never enters runtime.

The generated .tpl.php file is a derived artifact — re-running the compiler overwrites it. Edit the YAML, never the output.

Installation

Requires PHP 8.1+, the yaml extension, and migears/pages ^2.0 — the shared compiler, which pulls in migears/template ^2.0 to render what it emits.

Install the yaml extension on macOS:

On Linux, pecl install yaml usually works directly.

Make the built-in components findable by the template engine:

Or copy components/ into your project's template directory.

Quick Start

Write a page declaration views/pages/users.page.yaml:

Compile it:

This produces views/pages/users.tpl.php. Render it like any other template:

A complete example covering every syntax feature ships in examples/full-featured.page.yaml, with a minimal layout in examples/views/layout/main.php. Compile it in place and it renders straight away:

YAML Notes

The parser is libyaml (via ext-yaml), which follows YAML 1.1. Quote a value when it would otherwise be mis-parsed:

Case Wrong Right
Value starts with { / [ text: {{ user.name }} text: '{{ user.name }}'
Value starts with ! (tag prefix) when: !user.hidden when: '!user.hidden'
Value contains : text: 时间: 12:00 text: '时间: 12:00'
Value contains # (comment) text: a # b text: 'a # b'
Key starts with @ or : @click: go() "@click": go()

Also:

Front-end Framework Integration

Keys on a node fall into three groups:

  1. DSL fields — consumed by the node itself (heading.level, link.href, form.action), including structural children (then, body, fields, columns, data, options, content).
  2. Forwarded attributes — emitted on the tag the node produces:
    • "@event" — the Alpine / Vue event shorthand, written as a quoted key
    • any name containing a colon: x-on:click, x-bind:href, v-on:click, wire:click, on:click; ":href" needs quotes
    • prefixes x-, v-, hx-, data-
    • the HTML hooks class, id, style
  3. Everything else is a compile error — treated as a typo, never dropped silently.

Nodes that emit no tag of their own (text, if, each, component) reject forwarded attributes; wrap them in el instead. The page root likewise accepts only title / layout / body / sections.

Forwarded values are HTML-escaped first and interpolated second, so {{ }} works inside them (and single quotes stay readable). Scalars are normalised for HTML: 7 → "7", true → "true", x-cloak: → x-cloak="" (the YAML spelling of a valueless attribute); anything non-scalar is an error.

A forwarded name is emitted exactly as written, so it has to be a legal attribute name: whitespace, quotes, <, >, /, = and control bytes are compile errors (the XML front end refuses the same shapes while it parses, and refuses an <attr> name that is not one). The DSL's own literal attributes — link.href, link.target, form.action, field.name / id / placeholder, option value — are escaped the same way, so a quote in an href can no longer end the attribute early. Element text is not escaped: that part is yours, exactly as on a text node.

How this differs from XML

XML attribute names cannot contain @, so the XML variant spells it __click. YAML writes "@click" directly — there is no __ mapping here, and no <attr> node either, because a quoted YAML key can express any attribute name. Writing __click in YAML fails with a hint to use "@click".

Framework matrix

Framework Key style Result
Alpine x-on:click, x-bind:href, x-data, x-show, x-cloak: works
Alpine "@click" works (quoted key)
Alpine @click unquoted fails — YAML scan error; quote it
Alpine x-on-click (hyphen) rejected — Alpine only has the colon form
Vue v-on:click, v-bind:href, ":href" works
Vue "@click" works
htmx hx-get, hx-trigger works
Stimulus data-controller, data-action works
Livewire wire:click, wire:model.live works

One owner per region

Server-side and client-side rendering must not both own the same DOM region. Render structure with each / if / table on the server, then hang interaction on top with Alpine — do not also drive that list with x-for, or Alpine regenerates it and you get duplicated nodes plus flicker.

Data Binding

{{ path }} interpolates a dot path into an auto-escaped output:

Path Compiles to
{{ users }} ## $users ?? '' ##
{{ user.name }} ## $user['name'] ?? '' ##
{{ form.errors.email }} ## $form['errors']['email'] ?? '' ##

Rules:

Node Reference

Every node in body / sections is an object with a type field. Available types: text, heading, link, if, each, form, table, el, component. Nested structures (field, column) are typed by their position — they need no type, and a written one must match (field / column) or compilation fails.

Page root

Field Required Meaning
title no Page title; becomes the title section (only with layout)
layout no Layout template name, e.g. layout/main
body conditional Node tree when there is no layout
sections conditional Section name → node tree, required together with layout

layout + sections and body are mutually exclusive.

text / heading / link

if

Field Required Meaning
when yes Path, optional ! prefix (quote it: '!user.hidden')
then yes Node tree
else no Node tree

each

Field Required Meaning
items yes Path
as no Loop variable, default item
index no Index variable name
body yes Node tree

form

Field Required Meaning
action yes Form action
method no post (default) or get
fields yes Field array

Fields support these inputs: text (default), password, email, number, textarea, select, checkbox, hidden, submit.

Field Required Meaning
name yes Input name / id
label yes Label text; button text for submit
input no One of the inputs above
value no Bound path → value="## $path ?? '' ##"
required no Adds the required attribute
placeholder no text/password/email/number
options select only admin: 管理员 mapping
checked checkbox only Bound path; outputs checked when truthy
rows textarea only Default 4

select rejects value (selected-state binding is out of scope); options on a non-select field is a compile error.

table

Field Required Meaning
items yes Path
as no Row variable, default row
columns yes Column array
empty no Text shown for an empty list

Columns: label required; exactly one of pop (a data reference in braces, e.g. '{{ user.id }}' — the leading variable must be the table's as) or content (node tree in row scope). A field's id defaults to its name; bind names the front-end variable the framework binds to.

component

name required, data optional. Data values support {{ path }} and are compiled to PHP string concatenation.

Interpolated values reach the component unescaped — the component template owns escaping, choosing $this->e() for text or $this->raw() for trusted markup. Pre-escaping here would double-encode anything containing HTML. Among the built-ins, card.title / button.text / alert.text / badge.text go through e(), while card.body uses raw().

Built-in components (plain template files in components/, readable and copyable): card (title, body), button (text, href, type), alert (type, text), badge (text, type). Custom components are ordinary miGears Template files referenced by name.

Custom components

Write the file, make its directory findable, reference it by name — there is no registry, and the file's existence is not checked at compile time. examples/components/my-card.php is a runnable one, referenced from examples/full-featured.page.yaml:

A .tpl.php component works the same way — the engine compiles the ## ## sugar on first render:

## $expr ## compiles to $this->e($expr) and ### $expr ### to $this->raw($expr) — raw is one extra #, not a different function. So ## $this->raw($expr) ## does not give raw output: the sugar wraps it in e() anyway and quietly escapes, which is why the built-ins above are plain PHP. Every .tpl.php also leaves a compiled artifact in the template cache directory (writable; system temp by default) and wins over a same-named .php, while plain PHP output is never auto-escaped (<?= $title ?> prints raw) — the sugar's one real safety advantage.

el

tag required (lowercase HTML tag name); body is the child node tree and may be omitted (treated as empty); accepts any forwarded attribute. This is how wrapper attributes such as x-data get a home, since text / if / each emit no tag.

CLI

Errors

Compile errors throw MiGears\YamlPages\Exception\CompileException with a node path, e.g.:

The CLI prints errors to stderr with the file name; directory mode keeps going on failure.

Testing

Unit tests assert exact compiled output; integration tests render the compiled page through the full miGears Template pipeline. With migears/xml-pages checked out beside this package, FrontEndParityTest compiles the same page written in both syntaxes and requires the two artifacts to be identical — every fixture under tests/fixtures/pages has an XML twin, and every one under tests/fixtures/errors must be refused with the same message.

License

MIT


migears/yaml-pages

Version

基于 YAML 的声明式页面定义工具:把 .page.yaml 页面声明编译为 miGears 模板文件(.tpl.php),模板引擎在首次渲染时再将其编译为纯 PHP。YAML 声明是唯一事实标准;生成的模板是派生文件,不应手工修改。

特性

边界

范围内

范围外(刻意不做)

工作原理

刻意两次编译:

  1. yaml-pages 把 YAML 声明解析为 migears/pages 的数组 DSL,由那里的共享编译器翻译为 .tpl.php 糖语法(## $expr ##)。中间产物保持可读,每个 DSL 词汇对应什么模板语法一目了然。
  2. migears/template 的 TemplateCompiler 把糖编译成纯 PHP 模板(mtime 缓存,仅模板变更后重编一次)。渲染由 PHP 执行:模板运行时把变量以 HTML 形式输出给浏览器,声明层不进入运行期。

生成的 .tpl.php 是派生文件——重新编译即覆盖。修改 YAML,不要改产物。

安装

要求 PHP 8.1+、yaml 扩展,以及共享编译器 migears/pages ^2.0——它带来渲染产物所需的 migears/template ^2.0。

macOS 上安装 yaml 扩展:

Linux 上通常直接 pecl install yaml 即可。

让模板引擎能找到内置组件:

或把 components/ 拷入项目的模板目录。

快速开始

编写页面声明 views/pages/users.page.yaml:

编译:

生成 views/pages/users.tpl.php。与普通模板一样渲染:

覆盖全部语法特性的完整示例见 examples/full-featured.page.yaml,配套最小布局在 examples/views/layout/main.php。编译到该目录即可直接渲染:

YAML 编写注意

解析层是 libyaml(ext-yaml),遵循 YAML 1.1。以下写法必须引号包裹,否则会被误解析:

场景 错误写法 正确写法
值以 { / [ 开头 text: {{ user.name }} text: '{{ user.name }}'
值以 ! 开头(tag 前缀) when: !user.hidden when: '!user.hidden'
值内含 : text: 时间: 12:00 text: '时间: 12:00'
值内含 #(注释) text: a # b text: 'a # b'
键以 @ 或 : 开头 @click: go() "@click": go()

其余注意:

前端框架集成

节点上的键分三类:

  1. DSL 字段 —— 节点自己消费(heading.level、link.href、form.action),含结构性子键(then、body、fields、columns、data、options、content)。
  2. 透传属性 —— 输出到该节点生成的标签:
    • "@event" —— Alpine / Vue 的事件简写,写成带引号的键
    • 带冒号的名字:x-on:click、x-bind:href、v-on:click、wire:click、on:click;":href" 需要引号
    • 前缀:x-、v-、hx-、data-
    • HTML 钩子:class、id、style
  3. 其余一律编译错误 —— 视为拼写错误,绝不静默丢弃。

不输出标签的节点(text、if、each、component)不接受透传属性,用 el 包裹即可。页面根同理,只认 title / layout / body / sections。

透传值先转义、后插值,所以 {{ }} 在属性值里照常可用(单引号也保持可读)。标量按 HTML 属性的形态归一:7 → "7"、true → "true"、x-cloak: → x-cloak=""(无值属性的 YAML 写法);非标量报错。

透传的名字按原样写进标签,因此必须是合法的属性名:含空白、引号、<、>、/、= 或控制字符一律编译错误(XML 前端在解析时拒掉同样的形态,<attr> 名不合法同样报错)。DSL 自己的字面量属性——link.href、link.target、form.action、field.name / id / placeholder、option 的 value——现在走同一套转义,href 里的引号再也不会提前结束属性。元素文本不转义:那部分由你掌控,与 text 节点一致。

与 XML 版的差异

XML 的属性名装不下 @,所以那边用 __click 表示 @click。YAML 直接写 "@click" —— 这里没有 __ 映射,也不需要 <attr> 节点(引号键可以表达任何属性名)。在 YAML 里写 __click 会报错并提示改用 "@click"。

框架可用性

框架 键写法 结果
Alpine x-on:click、x-bind:href、x-data、x-show、x-cloak: 可用
Alpine "@click" 可用(引号键)
Alpine @click 裸写 失败 —— YAML 扫描错误,必须加引号
Alpine x-on-click(连字符) 拒绝 —— Alpine 只有冒号形式
Vue v-on:click、v-bind:href、":href" 可用
Vue "@click" 可用
htmx hx-get、hx-trigger 可用
Stimulus data-controller、data-action 可用
Livewire wire:click、wire:model.live 可用

同一区域只能有一个 owner

服务端渲染与客户端渲染不能同时拥有同一块 DOM。结构交给服务端的 each / if / table,交互挂在 Alpine 上——但不要再对该列表用 x-for,否则 Alpine 会用它的模板重新生成,结果是重复节点加闪烁。

数据绑定

{{ path }} 把点路径插值为自动转义输出:

路径 编译为
{{ users }} ## $users ?? '' ##
{{ user.name }} ## $user['name'] ?? '' ##
{{ form.errors.email }} ## $form['errors']['email'] ?? '' ##

规则:

节点参考

body / sections 中的每个节点都是带 type 字段的对象。可选类型:text、heading、link、if、each、form、table、el、component。内嵌结构(field、column)的类型由位置决定——不必写 type;若写出,值必须匹配(field / column),否则编译失败。

页面根

字段 必填 说明
title 否 页面标题,写入 title section(仅 layout 时生效)
layout 否 继承的布局模板名,如 layout/main
body 视情况 无 layout 时的节点树
sections 视情况 section 名 → 节点树,与 layout 搭配

layout + sections 与 body 互斥。

text / heading / link

if

字段 必填 说明
when 是 路径,支持 ! 前缀(记得加引号:'!user.hidden')
then 是 节点树
else 否 节点树

each

字段 必填 说明
items 是 路径
as 否 循环变量,默认 item
index 否 索引变量名
body 是 节点树

form

字段 必填 说明
action 是 表单提交地址
method 否 post(默认)或 get
fields 是 字段数组

字段支持以下 input:text(默认)、password、email、number、textarea、select、checkbox、hidden、submit。

字段 必填 说明
name 是 输入框 name / id
label 是 标签文本;submit 时为按钮文字
input 否 上述 input 之一
value 否 绑定路径 → value="## $path ?? '' ##"
required 否 输出 required 属性
placeholder 否 text/password/email/number
options 仅 select admin: 管理员 形式的映射
checked 仅 checkbox 绑定路径;真值时输出 checked
rows 仅 textarea 默认 4

select 不接受 value(选中态绑定不在范围内);options 用在非 select 字段上是编译错误。

table

字段 必填 说明
items 是 路径
as 否 行变量,默认 row
columns 是 列数组
empty 否 空列表时显示的文本

列:label 必填;pop(花括号形式的数据引用,如 '{{ user.id }}',首段必须是该表格的 as)与 content(行变量作用域内的节点树)二选一。字段的 id 默认等于 name;bind 是前端框架绑定的变量名。

component

name 必填,data 可选。data 值支持 {{ path }} 插值,编译为 PHP 字符串拼接。

插值值以未转义形式传给组件——转义由组件模板决定:文本用 $this->e(),信任的 HTML 用 $this->raw()。编译期预转义会与组件模板的转义叠成双重转义。内置组件中 card.title / button.text / alert.text / badge.text 走 e(),card.body 走 raw()。

内置组件(components/ 下的普通模板文件,可直接阅读复制):card(title、body)、button(text、href、type)、alert(type、text)、badge(text、type)。自定义组件是普通的 miGears Template 文件,按名引用。

自定义组件

写文件、让目录可被找到、按名引用——没有注册表,编译期也不检查文件是否存在。examples/components/my-card.php 就是一个可直接运行的自定义组件,由 examples/full-featured.page.yaml 引用:

.tpl.php 组件同样可用——引擎会在首次渲染时把 ## ## 糖编译成 PHP:

## $expr ## 编译为 $this->e($expr),### $expr ### 编译为 $this->raw($expr)——raw 是多一个 #,不是换一个函数;所以 ## $this->raw($expr) ## 不会原样输出,糖会再包一层 e() 静默转义,上面几个内置组件因此在原生 PHP 里写 $this->raw()。另外每个 .tpl.php 会在模板缓存目录留一份编译产物(目录需可写,未配置时是系统临时目录),且同名时优先于 .php;而原生 PHP 的输出永不自动转义(<?= $title ?> 原样输出),这是糖唯一的实质安全优势。

el

tag 必填(小写 HTML 标签名);body 为子节点树,可省略(视为空);接受任意透传属性。由于 text / if / each 自己不输出标签,这是给 x-data 这类包裹层属性找落点的唯一方式。

CLI

错误处理

编译错误抛出 MiGears\YamlPages\Exception\CompileException,信息带节点路径,例如:

CLI 将错误输出到 stderr 并附文件名;目录模式继续处理其余文件。

测试

单元测试断言编译产物,集成测试把编译产物经 migears/template 完整渲染验证。当 migears/xml-pages 与本包并排检出时,FrontEndParityTest 会把同一页面用两种语法各编译一次并要求产物完全一致——tests/fixtures/pages 下每个 fixture 都有对应的 XML 孪生文件,tests/fixtures/errors 下的每个则必须被同样的消息拒绝。

License

MIT


All versions of yaml-pages with dependencies

PHP Build Version
Package Version
Requires php Version ^8.1
ext-yaml Version *
migears/pages Version ^2.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package migears/yaml-pages contains the following files

Loading the files please wait ...