# Baklib开发者中心 - Full documentation
> Baklib 模板开发中心主要介绍了如何通过低代码开发基于Baklib Wiki模板,CMS 的站点模板,以及数字体验场景定制,包括Liquid语言、Tailwind CSS、API 的使用和配置。
This file contains the full Markdown content of each page. Append `.md` to any page URL to view a single page in Markdown format.
---
URL: https://dev.baklib.cn/overview/enter
Updated: 2024-11-17
## 标题
进入界面
## 内容
## 开发入口
当创建好一个应用以后,我们可以通过几个入口进入到模板开发界面。
### 1. 通过应用 welcome 界面进入
当创建好一个应用后,在 `welcome` 界面,可以看到“低代码开发平台”入口,点击进入。
### 
2. 通过应用管理界面进入
1. 当创建好一个应用后,在应用管理中的侧边栏导航中,点击【模板开发】进入。
2. 在【应用设置】--【界面展示】中,查看【模板】Tab栏,进入模板开发。
3. 在【首页布局】中,可以进入首页的模板开发(如果首页有多个展示主题,则这里可以切换不同的主题模板)。
### 
3. 通过页面管理界面进入
1. 在【页面管理】中,选择任意一个页面,在【内容编辑】--【页面模板】Tab里面可查看该页面的模板,点击并进入页面模板编辑。
2. 在【页面内容】Tab展示了当前页面模板定义的动态表单信息。
## 开发界面
进入模板开发界面,我们可以看到当前的模板信息;版本信息。
* 开发版本:为非固定版本,可进行编辑和修改。
* 发布版本:为固定版本,发布以后不可修改。

点击某个开发版本,进入代码编辑器界面,这里内置了一个在线的代码编辑器,用户可以在线进行实时编程和调试、预览。
1. 版本信息:提示当前所属的模板,以及当前的版本。
2. 目录结构:提示模板即有的文件目录结构,每一个目录具备不同的功能。
3. 代码编辑区域:代码编辑区域,代码往往由 HTML + Javascript + Liquid 语法组成。
4. 预览和保存:点击保存,新修改的内容就可以立刻应用到站点中,你可以刷新站点页面预览内容变化。

---
URL: https://dev.baklib.cn/theme/config
Updated: 2024-11-28
## 标题
config/
## 内容
该目录只有一个 `settings_schema.json` 配置文件,用于定义模板的元数据信息包括名称、作者、版本号,定义的全局变量等。这些信息对于标识和管理主题非常重要,同时在主题编辑器中也会显示该主题的基本信息。
---
URL: https://dev.baklib.cn/liquid/basics
Updated: 2025-01-02
## 标题
基础(Basics)
---
URL: https://dev.baklib.cn/guide/objects
Updated: 2024-12-09
## 标题
变量和方法
## 内容
本教程介绍 Liquid 模板开发中的变量和方法使用。
## **Object(对象)**
| 类型名称 | 解释 |
| --- | --- |
| site | 当前cms站点信息 |
| page | 页面的详细信息 |
| current_user | 当前登录用户信息 |
| tag | 标签 |
| author | 作者 |
| comment | 评论 |
| plugins.feedback | 用户反馈插件 |
### **site(当前站点)**
| 属性/方法 | 类型 | 解释 | 示例 |
| --- | --- | --- | --- |
| name | string | 站点名称 | 开心农场 |
| favicon_url | string | 站点图标 | <url> |
| time_zone | string | 站点时区 | Beijiang |
| language | string | 站点语言 | zh-CN \| en <html lang="{{ site.language }}"> |
| url | string | 网站地址 | https://help.baklib.com/ |
| password_login_enabled | boolean | 是否开启密码登录 | true \| false |
| sso_login_enabled | boolean | 是否开启 SSO 登录 | true \| false |
| baklib_login_enabled | boolean | 是否开启 Baklib 登录 | true \| false |
| nav_tree_path | | 树状导航地址 | /-/nav_tree |
| pages | page[] | 通过 PATH 查找页面, 返回query关系 . 支持 created_at/edited_at/visit_count 排序 | site.pages['/'] => 获取首页 site.pages['/blogs'] |
| comments | comment[] | 通过 id 查找页面, 返回query关系 . 支持 created_at/published_replies_count 排序 | site.pages['7zkpc0'] 获取对应评论 |
| pages_in_list | page[] | 获取全站的页面列表 | site.pages_in_list * 数组默认返回 50 条记录,你可以自定义返回记录数: \| limit: 100 |
| tags | tag[] | 站点所有标签列表,返回query关系 *-可选项,通过settings.tags自定义 | tags['tag_name'] => 获取指定名称的标签 site.tags(见下面 Tags 介绍) |
| plugins | json | 插件配置信息 | 见 plugins.feedback |
| settings | json | 站点模板定义的变量信息 | |
| theme_colors_css | string | 当前站点的主题颜色 | --theme-color-primary: 3 169 244 |
| mcp_url | string | 当前站点的mcp地址 | site.mcp_url |
### **current\_user(当前用户)**
| 属性/方法 | 类型 | 解释 | 示例 |
| --- | --- | --- | --- |
| name | string | 用户名称 | 张三 |
| image | string | 用户头像url | <url> |
| provider | string | 标标识用户的来源类型或认证方式。例如baklib sso dingtalk | baklib |
| department_ids | array | 用户所属部门id | [1,2] |
| group_ids | array | 用户所属用户组id | [] |
| employee_id | string | 用户组织架构中员工id | 123 |
| member_id | string | 用户的成员id | 123 |
| uid | string | oauth授权返回第三方平台用户的唯一标识与provider 共同唯一确定一个外部账号 | vwqAvmlqGqwiSkZ8syW4zogiEiE |
| id | string | provider是baklib情况下是用户id | |
| profile_url | string | 个人中心地址 | <url> |
| present? | boolean | 用户是否登录 | true \| false |
| blank? | boolean | !present? | true \| false |
| pages | page[] | 用户创建的页面集合 | |
### **page(页面)**
| 属性/方法 | 类型 | 使用方法 | 返回值 | 说明 |
| --- | --- | --- | --- | --- |
| id | string | page.id | 9g5hkd | 页面的ID唯一标识 |
| slug | string | page.slug | guide | 页面path/url的唯一标识 |
| link_text | string | page.link_text | 操作教程 | 页面标题 |
| path | string | page.path | /guide | 页面相对路径 |
| url | string | page.url | http://abc.example.com/guide | 页面绝对路径 |
| visits_count | integer | page.visits_count | 0 | 页面访问量 |
| edited_at | datetime | page.edited_at | | <待开放> |
| published_at | datetime | page.published_at | 2024-03-21 19:23:59 +0800 | {{ page.published_at \| time_ago }} {{ page.published_at \| date: "%Y-%m-%d" }} |
| seo_title | string | page.seo_title | | SEO 标题 |
| seo_keywords | string | page.seo_keywords | | SEO 关键词 |
| seo_description | string | page.seo_description | | SEO 描述 |
| settings | json{} | page.settings | {"title"=>"操作教程", "description"=>nil, "tags"=>[]} | page.settings.title page.settings.tags |
| author | author | page.author | | 本页面作者 page.author.name page.author.avatar_url |
| parent | page | page.parent | | 本页面的父页面 |
| children | page[] | page.children | | 子页面集合 *数组默认返回 50 条记录,你可以自定义返回记录数: page.children \|limit: 100 |
| children_in_list | page[] | page.children_in_list | | 子页面集合,排除不在列表中显示的。 |
| children_in_nav_menu | page[] | page.children_in_nav_menu | | 子页面集合,排除不在菜单中显示的。 |
| pages | page[] | page.pages | | 子孙页面集合 |
| pages_in_list | page[] | page.pages_in_list | | 子孙页面集合,排除不在列表中显示的。 |
| prev_page | page | page.prev_page | | 上一个页面 |
| next_page | page | page.next_page | | 下一个页面 |
| comments | comment[] | page.comments | | 页面评论集合 |
| breadcrumb | json | page.breadcrumb | | 页面面包屑 {"link_text"=>"首页", "path"=>"/"}{"link_text"=>"操作教程", "path"=>"/guide"} |
| visitor_posted_feedback | boolean | page.visitor_posted_feedback | false | 是否已提交反馈 |
| last_feedback_emoji | string | page.last_feedback_emoji | | 反馈的项 |
| versions | page[] | page.versions | | 版本页面集合 |
| markdown_path | string | page.markdown_path | | 当前页面的markdown 输出path(请配合 页面属性 to_markdown 属性 模板变量 Markdown 输出) |
| markdown_url | string | page.markdown_url | | 当前页面的markdown 输出url(请配合 页面属性 to_markdown 属性 模板变量 Markdown 输出) |
### **Comment(页面)**
| 属性/方法 | 类型 | 使用方法 | 返回值 | 说明 |
| --- | --- | --- | --- | --- |
| id | string | comment.id | 9g5hkd | 评论的ID唯一标识 |
| body | string | comment.body | guide | 评论的内容 |
| created_at | datetime | comment.created_at | | 评论创建时间 { page.created_at \| time_ago }} {{ page.created_at \| date: "%Y-%m-%d" }} |
| author | author | comment.author | | 评论作者 |
| reply_to_user | author | comment.reply_to_user | | 回复内容作者 |
| target | page | comment.target | | 评论主题 |
| parent | comment | comment.parent | | 回复的评论 |
| root | comment | comment.root | | 评论所属一级评论 |
| replies | comment[] | comment.replies | | 评论回复集合 |
### **version(版本)**
返回当前 `page` 页面的前 50 个版本信息。
| 属性/方法 | 类型 | 解释 | 示例 |
| --- | --- | --- | --- |
| name | string | 版本名称 | v1.0 |
| url | string | 版本 URL | url |
用法
{% assign version_count = page.versions | size %}
{% if version_count > 0 %}
{{ "search.result.t1" | t }} {% if search.tag %} {{ search.tag.name }} {% endif %} {% if search.keywords %} {{ search.keywords }} {% endif %} {{ "search.result.t2" | t }}
{% endif %} #### **Breadcrumb** 用户可以通过 `page.breadcrumb` 输出的 JSON 数组,自己循环生成,如: `themes/cms/test/snippets/_breadcrumb.liquid` {% comment %} @params breadcrumb array of objects with keys: link_text: string path: string {% endcomment %}#引用: page.liquid {% render 'breadcrumb', breadcrumb: page.breadcrumb %}#实现: snippets/_breadcrumb.liquid # 前端最佳实践一个优秀的面包屑导航需要满足:1)移动端不会因为面包屑太长而被挤压;超出的部分可自动水平滚动;2)文本不会因为被挤压而截断。前端生成的代码:theme_info,不能为其他值,表示此配置段为主题模版信息。 |
| theme_name | 是 | 字符串 | 主题模版的名称标识。只允许字母、数字、下划线的组合,如: help_center |
| theme_label | 否 | 字符串 | 主题模版的显示名称,如:帮助中心。 |
| theme_version | 是 | 字符串 | 主题模版的版本号,格式遵循 1.0.0 标准,用户使用模版时,可选择指定版本的模版。 |
| theme_scope | 是 | 字符串 | 主题模板的类型。只允许填写:community、cms、wiki |
| theme_author | 是 | 字符串 | 模版开发者 |
| theme_description | 是 | 字符串 | 描述 |
| theme_documentation_url | 否 | 字符串 | 文档地址 |
| theme_support_url | 否 | 字符串 | 技术支持地址 |
| theme_thumb_url | 是 | 字符串 | 缩略图地址 |
| theme_preview_images | 是 | 字符串数组 | 预览图,数组 |
| theme_languages | 否 | 字符串数组 | 多语言支持,填写数组,如['en', 'zh-CN', 'ja']表示支持英语、简体中文、日语。允许填写的值参考下表“多语言支持名单” |
| color_schemas | 否 | 哈希值 | 默认主题颜色配置 |
| theme_syntax_version | 是 | 字符串 | v2。不建议添加v1或不添加此值。 |
| miniprogram | 否 | 布尔 | true: 在使用此模板的站点后台中开启小程序下载、配置功能;请在模板适配小程序展示与功能后开启此选项 |
## 配置 name 为其它值表示站点配置项
| 属性名称 | 必填 | 类型 | 说明 |
| --- | --- | --- | --- |
| name | 是 | 字符串 | 此属性的值必填,不能是theme_info,此名称会展示在站点管理后台 |
| settings | 是 | 哈希数组 | 在此定义站点的动态配置项,会展示在站点管理后台。模板代码中可通过 site.settings 获取站点配置的值 |
| settings[x].id | 是 | 字符串 | 配置项的标识,如logo_url,模版代码中可通过 site.settings.logo_url 获取值 |
| settings[x].type | 是 | 字符串 | 配置项的类型,支持的配置类型参考下表“Setting支持的类型” |
| settings[x].label | 是 | 字符串 | 配置项的显示名称 |
| settings[x].info | 否 | 字符串 | 配置项的描述信息 |
| settings[x].default | 否 | | |
| settings[x].placeholder | 否 | | 输入框的提示文字 |
## 附录
### 多语言支持名单
# 中文
'zh-CN' => '中国大陆简体'
'zh-TW' => '台湾繁体'
'zh-HK' => '香港繁体'
'zh-MO' => '澳门繁体'
'zh-SG' => '新加坡简体'
# 英语
'en' => '通用英语'
'en-US' => '英语 (美国)'
'en-GB' => '英语 (英国)'
'en-AU' => '英语 (澳大利亚)'
'en-CA' => '英语 (加拿大)'
'en-NZ' => '英语 (新西兰)'
'en-IE' => '英语 (爱尔兰)'
# 葡萄牙语
'pt' => '通用葡萄牙语'
'pt-BR' => '葡萄牙语 (巴西)'
'pt-PT' => '葡萄牙语 (葡萄牙)'
# 西班牙语
'es' => '通用西班牙语'
'es-ES' => '西班牙语 (西班牙)'
'es-MX' => '西班牙语 (墨西哥)'
'es-AR' => '西班牙语 (阿根廷)'
# 法语
'fr' => '通用法语'
'fr-FR' => '法语 (法国)'
'fr-CA' => '法语 (加拿大)'
'fr-BE' => '法语 (比利时)'
'fr-CH' => '法语 (瑞士)'
# 德语
'de' => '通用德语'
'de-DE' => '德语 (德国)'
'de-AT' => '德语 (奥地利)'
'de-CH' => '德语 (瑞士)'
# 其他主要语言
'ja' => '日语'
'ko' => '韩语'
'vi' => '越南语'
'th' => '泰语'
'id' => '印尼语'
'ms' => '马来语'
'ar' => '阿拉伯语'
'hi' => '印地语'
'bn' => '孟加拉语'
'ru' => '俄语'
'tr' => '土耳其语'
### Setting支持的类型
| 类型 | 名称 |
| --- | --- |
| header | 段落标题 |
| paragraph | 段落描述 |
| text | 单行文字输入框 |
| number | 数字输入框 |
| range | 数字范围 |
| textarea | 多行文字输入框 |
| richtext | 富文本输入框 |
| html | HTML 源代码输入框 |
| liquid | Liquid 源代码输入框 |
| link | 链接输入框 |
| checkbox | 复选框 |
| radio | 单选项 |
| select | 下拉选择框 |
| color | 颜色选择器 |
| color_background | 背景颜色选择器 |
| date | 日期选择器 |
| font_picker | 字体选择器 |
| image_picker | 图片选择器 |
| video_picker | 视频选择器 |
| type 值 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| checkbox | True/False | false | |
| color_background | 颜色值 | | 背景颜色选择器,可以生成渐变色。颜色值在模板中的使用方法: <!-- 方法 1 --> <div style="height: 32px; background-image: {{ site.settings.banner_bg_color }}"></div> <!-- 方法 2 --> <div style="height: 32px; background-image: linear-gradient({{ site.settings.banner_bg_color.degree }}deg, {{ site.settings.banner_bg_color.from }}, {{ site.settings.banner_bg_color.to }}"></div> |
| | | | |
---
URL: https://dev.baklib.cn/theme/layout/theme
Updated: 2024-07-19
## 标题
theme.liquid
## 内容
### 文件内容
{% meta_tags %}
{{ 'editor.css' | asset_url | stylesheet_tag: data-turbo-track: 'reload' }}
{{ 'javascripts/main.js' | asset_url | script_tag: defer: true, data-turbo-track: 'reload' }}
{{ 'css/main.css' | asset_url | stylesheet_tag: data-turbo-track: 'reload' }}
{%# 引用外部资源 %}
{%# 引用site全局变量 %}
{{ site.settings.head_html }}
文件路径
|是否必须
|类型
|说明
|使用方式
| | --- | --- | --- | --- | --- | |baklib/shared/editor.css
|⚙️ 可选(如模版中需要使用富文本编辑器)
|样式 (CSS)
|富文本编辑器输出样式文件,使用 TailwindCSS 构建,控制编辑器基础样式(如段落、标题、列表、代码块等)。
baklib/shared/main.css
|✅ 必须
|样式 (CSS)
|全局共享样式文件,提供 bkt- 前缀的 TailwindCSS 公共组件与颜色系统,避免污染外部 CSS 命名空间。
在模板主布局中加载:{{ 'baklib/shared/main.css' \| asset_url \| stylesheet_tag: data-turbo-track: 'reload' }}
baklib/shared/editor.js
|⚙️ 可选(如模版中需要使用富文本编辑器)
|脚本 (JS)
|编辑器核心逻辑脚本,包含富文本编辑、组件注册、事件绑定等。
| | |baklib/shared/main.js
|✅ 必须
|脚本 (JS)
|全局前端逻辑js入口文件,自动导入全站通用模块:
• turbo — 启用 Turbo Drive/Frame 支持
• stimulus — 初始化 Stimulus 控制器
• ai_search_completion — 启用 AI 搜索建议(stimulus controller)
• expandable_content — 处理可展开内容交互(stimulus controller)
• responsive_attr — 响应式属性调整逻辑(stimulus controller)
在模板主布局中加载:{{ 'baklib/shared/main.js' \| asset_url \| script_tag: data-turbo-track: 'reload' }}
baklib/shared/ai_search_completion.js
|⚙️ 可选(仅在开启 AI 搜索建议时需要)
|脚本 (JS)
|提供 AI 搜索功能,用于站内搜索输入框或 AI 助手模块。默认由baklib/shared/main.js导入
baklib/shared/stimulus.js
|⚙️ 可选(如页面需要使用 Stimulus js)
|脚本 (JS)
|启用 Stimulus 控制器的初始化入口,负责连接 data-controller 标记的组件。默认由baklib/shared/main.js导入
baklib/shared/turbo.js
|⚙️ 可选(如页面需要使用 Turbo Frames / Turbo Streams)
|脚本 (JS)
|用于支持 Turbo Drive、Turbo Frames 和 Streams 的前端导航与局部更新。默认由baklib/shared/main.js导入
模版中使用turbo时请勿多次导入子模块,统一使用同一个模块实例,否则可能导致未知冲突问题,可能造成页面turbo导航混乱等问题;baklib/shared/main.js 和 baklib/shared/turbo.js 勿同时使用,默认挂载至window.Turbo
| --- URL: https://dev.baklib.cn/theme/locales/en-json Updated: 2024-07-19 ## 标题 en.json ## 内容 { "theme_label": "Daisy Wiki", "theme_description": "The web framework for content-driven website based on DaisyUI.", "generic": { "menu": "Menu", "theme": "Theme", "close": "Close", "back": "Back", "search": "Search", "popular_search": "Popular Search", "search_result": "related searching result", "index": "Home", "articles": "articles", "read_more": "read more", "404": "404 not found", "403": "403 No access permission", "empty": "content is empty", "sub_page_list": "Sub Pages", "copyright": "All rights reserved", "published_at": "Published at", "prev_page": "previous page", "next_page": "next page", "hot_pages": "Hot visit articles", "recent_pages": "Recent articles", "tags": "Tags" }, "placeholders": { "search": "Searching..", "input_password": "Please input your password" }, "buttons": { "submit": "Submit", "login": "Login", "sso_login": "SSO Login", "baklib_login": "Baklib Account Login" }, "prompts": { "page_restricted": "This page can only be accessed with authentication" }, "feedback": { "title": "Submit Feedback", "input_placeholder": "Please input feedback" } } --- URL: https://dev.baklib.cn/theme/snippets/header Updated: 2024-07-19 ## 标题 _header.liquid ## 内容 {% assign screen_width = site.settings.screen_width.value | default: 'max-w-screen-xl' %}Everything you need to deploy your app
Quis tellus eget adipiscing convallis sit sit eget aliquet quis. Suspendisse eget egestas a elementum pulvinar et feugiat blandit at. In mi viverra elit nunc.
Incididunt sint fugiat pariatur cupidatat consectetur sit cillum anim id veniam aliqua proident excepteur commodo do ea.
模板页面 HTML
类型名称
|解释
| | --- | --- | |site
|当前cms站点信息
| |page
|页面的详细信息
| |tag
|标签
| |author
|作者
| |comment
|评论
| |current_user
|当前登录用户
| |plugins.feedback
|用户反馈插件
| ### **site(当前站点)(同cms站点)** |属性/方法
|类型
|解释
|示例
| | --- | --- | --- | --- | |name
|string
|站点名称
|开心农场
| |favicon_url
|string
|站点图标
|<url>
| |time_zone
|string
|站点时区
|Beijiang
| ### **page(页面)(同cms站点)** |属性/方法
|类型
|使用方法
|返回值
|说明
| | --- | --- | --- | --- | --- | |id
|string
| |9g5hkd
|页面的ID唯一标识
| |slug
|string
|page.slug
|guide
|页面path/url的唯一标识
| |link_text
|string
|page.link_text
|操作教程
|页面标题
|属性/方法
|类型
|使用方法
|返回值
|说明
| | --- | --- | --- | --- | --- | |id
|string
|comment.id
|9g5hkd
|评论的ID唯一标识
| |body
|string
|comment.body
|guide
|评论的内容
| |created_at
|datetime
|comment.created_at
| |评论创建时间
{ page.created_at \| time_ago }} {{ page.created_at \| date: "%Y-%m-%d" }}
| |author
|author
|comment.author
| |评论作者
| |reply_to_user
|author
|comment.reply_to_user
| |回复内容作者
| |target
|page
|comment.target
| |评论主题
| |parent
|comment
|comment.parent
| |回复的评论
| |root
|comment
|comment.root
| |评论所属一级评论
| |replies
|comment[]
|comment.replies
| |评论回复集合
| ### **current\_user(当前登录用户)同cms站点)** |uid
|string
|current_user.uid
|10001
|用户的ID唯一标识
| | --- | --- | --- | --- | --- | |name
|string
|current_user.name
|张三
|用户名称
| |image
|string
|current_user.image
|http://site-5zw8rxj1.free.lvh.me:3000/-/avatars/ey…CJ9fQ==--f3bb19439273b4e1f05ffbdbd9ce7108485c7f75
|用户头像地址
| |member_id
|integer
|current_user.member_id
| |用户成员的ID唯一标识
| |profile_url
|string
|current_user.profile_url
|http://tanmer.lvh.me:3000/my/profile
|个人中心链接
| |pages
|page[]
|current_user.pages
| |当前用户创建的页面集合
| ### **tag(标签)同cms站点)** |属性/方法
|类型
|解释
|示例
| | --- | --- | --- | --- | |path
|string
|标签页面的路径
|/-/tags/AxdEf
| |name
|string
|名称
|测试标签
| |color
|string
|字体颜色
|#42445A
| |bg_color
|string
|背景颜色
|#42445A
| |color_hls
|string
|颜色计算
|background-color: hsl({{ tag.color_hls[0] }}, {{ tag.color_hls[1] }}%, 90%);
| |pages_count
|integer
|含有该标签的页面数量
|<待开放>
| |pages
|page[]
|含有该标签的页面列表
| | 页面的标签通过在 `settings` 中动态定义,通过 `page.settings.tags` 方法调用。 {% schema %} { "settings": [ { "id": "tags", "type": "tag_picker", "multiple": true, "label": "标签" } ] } {% schemaend %} * 页面中的调用示例: ^ {% for tag in page.settings.tags %} {{ tag.name }} {% endfor %} site.tags 则返回当前站点的 Tag 标签集合属性/方法
|类型
|解释
|示例
| | --- | --- | --- | --- | |name
|string
|作者名称
|张三
| |avatar_url
|string
|作者头像
| | 操作示例: {% assign avatar_url = 'images/icons/icon.svg' | asset_url %}属性/方法
|类型
|解释
|示例
| | --- | --- | --- | --- | |helpful_types
|Array(JSON)
|用户可选择的表情列表
|plugins.feedback.helpful_types
| |helpful_types[0].emoji
|string
|表情符
|😊
| |helpful_types[0].label
|string
|表情符对应的意思
|有用
| |helpful_label
|string
|提示用户选择表情
|您的反馈是对我们的产品极其重要
| |message_enabled
|boolean
|是否启用反馈留言
| | |message_required
|boolean
|当开启反馈留言,反馈留言是否必填
| | |login_required
|boolean
|反馈是否必须登录
| | ## **Filter(函数)** |名称
|解释
| | --- | --- | |order_by
|排序
| #### **order\_by** 对`page`列表进行排序,排序规则: |参数
|解释
| | --- | --- | |created_at
|按照创建时间排列
| |edited_at
|按照修改时间排列
| |visits_count
|按照访问量排列
| > ***在参数前添加***`-`,代表倒序排列 示例: {% assign tag_pages = tag.pages | order_by: '-created_at' %} |名称
|解释
| | --- | --- | |where
|筛选
| #### **where** 对`page`列表进行筛选,筛选参数 |参数
|解释
| | --- | --- | |template_name
|模板名称
| 示例: {% assign pages = search.pages | where: 'template_name', 'post' %} |名称
|解释
| | --- | --- | |feedback_count
|反馈数量
| |feedback_type_count(page, useful_type)
|某个反馈类型的反馈数量
| #### **feedback\_count、feedback\_type\_count** 获取`page`的反馈数量 示例: {{ page | feedback_type_count: '😊' }} //😊表情的反馈数量 {{ page | feedback_count }} //页面总反馈数 |roots
|一级评论
| #### **roots** `comment`列表一级评论 示例: {{ post.comments | roots | size }} --- URL: https://dev.baklib.cn/liquid/filters/abs Updated: 2025-01-02 ## 标题 abs ## 内容 返回一个数字的绝对值。 输入 {{ -17 | abs }} 输出 17 输入 {{ 4 | abs }} 输出 4 如果组成字符串的各个字符全是数字,`abs` 也能够对此字符串求绝对值。 输入 {{ "-19.86" | abs }} 输出 19.86 --- URL: https://dev.baklib.cn/api/55c38 Updated: 2025-08-05 ## 标题 📢 接口更新声明 · 2025 年 8 月 5日 ## 内容 ``` --- 为提升接口一致性与功能完备性,`Baklib` 已对页面内容相关接口做出以下更新: --- ### 🔁 1. 页面详情查询接口区分 `id` 与 `full_path` * **通过 ID 查询页面详情(保留原接口)** `GET /v1/sites/{site_id}/pages/{page_id}` * **通过 full\_path 查询页面详情(新接口,之前通过/v1/sites/{site_id}/pages/{page_id}传递full_path查询废弃)** `GET /v1/sites/{site_id}/pages/by_path/{full_path}` ⚠️ `full_path` 需进行 URL 编码(如 `encodeURIComponent`)以避免路由冲突。 --- ### ✏️ 2. 页面草稿查询接口新增 * **通过 ID 获取草稿内容:** `GET /v1/sites/{site_id}/pages/{page_id}/draft` * **通过 full\_path 获取草稿内容:** `GET /v1/sites/{site_id}/pages/by_path/{full_path}/draft` --- ### 🕓 3. 页面版本内容接口新增 #### ✅ 支持通过 ID 与 full\_path 两种路径访问页面版本信息: | 操作 | 通过 page\_id 路径 | 通过 full\_path 路径 | | ------ | ------------------------------------------------------------------ | ---------------------------------------------------------------------------- | | 获取版本列表 | `GET /v1/sites/{site_id}/pages/{page_id}/versions` | `GET /v1/sites/{site_id}/pages/by_path/{full_path}/versions` | | 获取单个版本 | `GET /v1/sites/{site_id}/pages/{page_id}/versions/{version_id}` | `GET /v1/sites/{site_id}/pages/by_path/{full_path}/versions/{version_id}` | | 创建版本 | `POST /v1/sites/{site_id}/pages/{page_id}/versions` | `POST /v1/sites/{site_id}/pages/by_path/{full_path}/versions` | | 更新版本 | `PUT /v1/sites/{site_id}/pages/{page_id}/versions/{version_id}` | `PUT /v1/sites/{site_id}/pages/by_path/{full_path}/versions/{version_id}` | | 删除版本 | `DELETE /v1/sites/{site_id}/pages/{page_id}/versions/{version_id}` | `DELETE /v1/sites/{site_id}/pages/by_path/{full_path}/versions/{version_id}` | > ⚠️ 所有通过 full\_path 查询的接口都要求将full_path转义编码。 --- ### 🗑 4. 页面列表默认不返回已删除数据 * **获取页面列表(默认仅返回未删除页面):** `GET /v1/sites/{site_id}/pages` * **如需获取回收站中的已删除页面,请传入参数:** `GET /v1/sites/{site_id}/pages?deleted=true` --- ### ✅ 总结更新内容一览 | 功能模块 | 说明/变更 | | -------- | ------------------------------------------------------------- | | 页面详情查询 | 区分 ID 与 full\_path 查询方式,full\_path 新增专用路径 | | 页面草稿接口 | 新增通过 ID 或 full\_path 获取草稿内容的接口 | | 页面版本接口 | **新增完整的版本内容 CRUD 接口**,支持通过 ID 与 full\_path 路径访问 | | 页面列表行为调整 | 默认不返回删除页面,如需获取回收站数据请添加 `deleted=true` 查询参数 | | URL 编码提醒 | 所有涉及 full\_path 的接口必须对路径进行 URL 编码(如使用 `encodeURIComponent()`) | --- 如对更新内容有任何疑问,请联系技术支持。建议所有接入方及时适配新的接口路径,并根据需要对 `full_path` 做 URL 编码处理,确保兼容性与稳定性。 --- ``` --- URL: https://dev.baklib.cn/liquid/e1712/8bb8d Updated: 2025-09-12 ## 标题 动态表单 - setting 默认值引用 ## 内容 当在settings配置中需要为默认值添加复杂的值时,可通过使用 `preset:`关键字引用 presets 目录下的文件 ##### **示例**: 模版根目录添加presets文件夹,并添加 footer_nav_links.html 文件 - snippets - footer_nav_links.html - styles - templates # setting 默认值引用 footer_nav_links.html 的内容作为默认值 { "id": "footer_nav_links", "type": "code", "language": "html", "label": "t:schema.settings.footer.nav_links.label", "info": "t:schema.settings.footer.nav_links.info", "default": "preset:footer_nav_links.html" } --- URL: https://dev.baklib.cn/theme Updated: 2024-11-28 ## 标题 目录结构 ## 内容 主题模板决定了用户站点的布局、功能和样式。模板主题是使用`Liquid`以及`HTML`,`CSS`,`JavaScript`和`JSON`构建的,使用这些语言,开发人员可以创建客户想要的任何外观。同时提供了多种工具和最佳实践来加速开发过程。 > ***作为开发人员,您可以为特定客户构建自定义主题模板以满足客户的需求,或构建要在模板商店中销售的模板。*** ## **概述** 主题模板决定了用户站点的布局、功能和样式。主题代码需要按照主题的标准目录结构组织,同时还包括配套资源,如`images`,`stylesheets`和`scripts`。 ## **文件资源** 主题文件分为以下一般类别: * 标记和功能 - 这些文件控制主题的布局和功能。他们使用Liquid生成站点页面的HTML标记。 * 配套资源 - 这些文件是主题中其他文件调用或使用的资产、脚本或本地化文件。 * 配置文件 - 这些文件使用JSON存储配置数据,用户可以通过主题编辑器进行自定义设置。 ## **目录结构** 模板固定的目录结构: . ├── assets └── images └── css └── javascripts └── ... ├── config └── settings_schema.json ├── layout └── theme.liquid ├── locales ├── src ├── snippets └── templates ## **目录介绍** 一个名为 `docs` 的模板的目录结构如下所示:`themes/cms/docs/` | |一级目录
|二级目录
|备注
| | --- | --- | --- | --- | | |assets/
| | | | | |css/
|存放从 src 中编译后的 css 文件
| | | |javascripts/
|存放从 src 中编译后的 js 文件
| | | |images/
|存放本地引用的资源
| | |config/
| | | | | |settings_schema.json
|存放模板的配置信息
| | |layout/
| | | | | |theme.liquid
|模板框架布局文件,其他模板文件都
| | |locales/
| |多语言版本翻译文件
| | |src/
| |原始 css/js 资源文件
| | |snippets/
| |存放模板页面片段
| | |statics/
| |存放静态模板文件
| | |templates/
| |存放模板文件,必须有一个 index.liquid
.gitignore
| |git 忽略文件
| | |package-lock.json
| |js 库打包文件
| | |package.json
| |js 库打包文件
| | |README.md
| |模板教程
| | |tailwind.config.js
| |TailwindCss 框架引用文件
| | |yarn.lock
| |yarn 打包文件
| --- URL: https://dev.baklib.cn/theme/assets Updated: 2024-07-19 ## 标题 assets/ ## 内容 资源文件目录,存放 css 、javascript、图片、字体等文件,通过 `asset_url` 方法生成可访问的 URL。 ## 示例 ### 插入 css 文件 把网站样式文件存放在 `assets/stylesheets/application.css` {{ 'stylesheets/application.css' | asset_url | stylesheet_tag: data-turbo-track: 'reload' }} 渲染输出 ### 插入 javascript 文件 把 javascript 文件存放在 `assets/javascripts/application.js` {{ 'javascripts/application.js' | asset_url | script_tag: defer: true, data-turbo-track: 'reload' }} 渲染输出 ### 显示图片 把图片存放`assets/images/welcome.png`
渲染输出
---
URL: https://dev.baklib.cn/liquid/tags
Updated: 2025-01-02
## 标题
标记(Tags)
## 内容
条件判断、循环、变量和注释。
---
URL: https://dev.baklib.cn/guide/forms
Updated: 2024-12-09
## 标题
动态表单
## 内容
用于模版定义动态字段,设计的表单类型,以达到自定义模版变量的目的:
# **表单 type: **`checkbox`
| Param
|Description
|Input
| | --- | --- | --- | |Type
|—
|checkbox
| |Label
|—
| | |Default
|—
|0 1 false true
| |Info
|—
| | **前端变量值** 类型:TrueClass true **前端变量显示** \{\{page.settings.foo}} `true` **示例:** 表单代码: { "id": "recommend_to_index", "type": "checkbox", "label": "推荐到首页展示", "default": true } --- 表单预览:  # **表单 type: **`color` |Param
|Description
|Input
| | --- | --- | --- | |Type
|—
|color
| |Label
|—
| | |Default
|—
|#00AA00
| |Colors
|—
|#FF0000\|#00FF00\|#0000FF
| |Info
|—
| | **前端变量值** 类型:String **前端变量显示** \{\{ page.settings.text\_color }} `#00AA00` **示例:** 代码: { "id": "text_color", "type": "color", "label": "Hero 文字颜色" } --- 预览:  # **表单 type: **`color_background` |Param
|Description
|Input
| | --- | --- | --- | |Id
|—
|bg_color
| |Label
|—
| | |Info
|—
| | |Default
|—
|{"from":"#0F69E8","to":"#1C0597"}
| |Colors
|—
|rgba(244, 67, 54, 1)\|rgba(233, 30, 99, 1)
| **前端变量值** 类型:DynamicForm::ColorBackgroundComponent::Value **前端变量显示** \{\{page.settings.bg\_color}} `linear-gradient(90deg, #0F69E8, #1C0597)` \{\{page.settings.bg\_color.to}} `#1C0597` \{\{page.settings.bg\_color.degree}} `90` \{\{page.settings.bg\_color.from}} `#0F69E8` **示例:** 代码: { "id": "banner_background", "label": "Hero 背景色", "type": "color_background" } --- 预览:  # **表单 type: **`date` |Param
|Description
|Input
| | --- | --- | --- | |Type
|—
|date
| |Label
|—
|foo
| |Default
|—
|2024-01-28
| |Info
|—
|这是一个日期选择器
| **前端变量值** 类型:Date "2024-01-28" **前端变量显示** \{\{page.settings.foo}} `2024-01-28` **示例:** 代码: { "id": "start_at", "type": "date", "label": "开始时间", "default": "2025-01-01" } --- 预览:  # **表单 type: **`font_picker` |Param
|Description
|Input
| | --- | --- | --- | |Type
|—
|font_picker
| |Label
|—
| | |Default
|—
|arial
| |Fonts
|—
|["system-ui", "arial"]
| |Info
|—
|选择一个字体
| **前端变量值** 类型:String "arial" **前端变量显示** \{\{page.settings.font\_name}} `arial` **示例:** 代码: { "id": "font", "type": "font_picker", "label": "字体", "default": "Arial" } --- 预览: # **表单 type: **`header` 动态表单分类标题,用于分组表单字段。 > \* 没有前端变量 |Param
|Description
|Input
| | --- | --- | --- | |Content
|—
| | **示例:** 代码: { "type": "header", "content": "分组 1" } --- 预览:  # **表单 type: **`paragraph` 这是一段文字介绍,用于动态表单的说明文字, 支持安全的 **HTML** 标签,自动过滤 script 标签。 > \* 没有前端变量 |Param
|Description
|Input
| | --- | --- | --- | |Content
|—
| | **示例:** 代码: { "type": "paragraph", "content": "paragraph" } --- 预览:  # **表单 type: **`html` |Param
|Description
|Input
| | --- | --- | --- | |Id
|—
|google_ads
| |Label
|—
|谷歌广告代码
| |Default
|—
| | |Info
|—
|粘贴谷歌广告 HTML 代码
| **前端变量值** 类型:ActiveSupport::SafeBuffer "这是蓝色粗体字" **前端变量显示** \{\{page.settings.google\_ads}} `这是蓝色粗体字` **示例:** 代码: { "id": "third_party_video_url", "type": "html", "label": "Youtube或其他视频地址", "info": "" } } }, "page": { "name": "Page", "description": "Document content page", "settings": { "description":{ "label": "Description" }, "content":{ "label": "Content", "info": "Synchronized from data source, cannot be edited" }, "icon": { "label": "ICON", "info": "1:1 ratio is recommended" }, "tags":{ "label": "Tags" } } } } } --- URL: https://dev.baklib.cn/theme/snippets/breadcrumb Updated: 2024-07-19 ## 标题 _breadcrumb.liquid ## 内容 {% comment %} @params breadcrumb array of objects with keys: link_text: string path: string {% endcomment %} --- URL: https://dev.baklib.cn/theme/templates/page Updated: 2024-07-19 ## 标题 page.liquid ## 内容 页面模板,位于 `templates/page.liquid`{{ "generic.tags" | t }}
{% for tag in page.settings.tags %} {{ tag.name }} {% endfor %}属性/方法 | 类型 | 解释 | |
|---|---|---|---|
page[parent_full_path] | string | 父页面full_path,可以指定创建页面的父级 | |
page[name] | string | 页面名称 | |
page[template_name] | string | 页面模板名称 | |
page[template_style] | string | 页面模板风格, 同一个模板页面可以有不同风格并切换,例如index.doc.liquid index.list.liquid, 页面使用模板template_name.template_style | |
page[published] | string | true false页面发布状态 | |
page[template_variables] | string | 模板变量 | |
page[template_variables][title] | string | { "id": "title", "type": "text", "placeholder": "", "label": "标题", "info": "显示在正文上方的文章标题" } , 模板setting里可以设置的变量 | |
page[template_variables][content] | html | { "id": "content", "type": "richtext", "label": "问题内容" } | |
return_template_name | 修改成功返回页面,默认跳转详情页 | ||
属性/方法 | 类型 | 解释 | |
|---|---|---|---|
page[published] | string | true false页面发布状态 | |
page[template_variables] | string | 模板变量 | |
page[template_variables][title] | string | { "id": "title", "type": "text", "placeholder": "", "label": "标题", "info": "显示在正文上方的文章标题" } , 模板setting里可以设置的变量 | |
page[template_variables][content] | richtext | { "id": "content", "type": "richtext", "label": "问题内容" } | |
return_template_name | 修改成功返回页面,默认跳转详情页 | ||
属性/方法 | 类型 | 解释 | |
|---|---|---|---|
feedback[useful_type] | string | 😊 😞, 反馈表情 | |
feedback[message] | string | 反馈具体信息 | |
属性/方法 | 类型 | 解释 | |
|---|---|---|---|
target_full_path | string | 评论页面full_path | |
reply[published] | string | true, false评论发布状态 | |
reply[root_id] | string | 一级评论id | |
reply[parent_id] | string | 回复评论id | |
reply[body] | richtext | 回复内容 | |
return_template_name | string | 修改成功返回处理页面 | |
属性/方法 | 类型 | 解释 | |
|---|---|---|---|
name | string | 输入框name,page[template_variables][content] | |
content | richtext | 编辑器内容,content | |
toolbar | string | 工具栏,例如toolbar、simple | |
==
相等
| | --- | --- | |!=
不相等
| |>
大于
| |<
小于
| |>=
大于或等于
| |<=
小于或等于
| |or
逻辑或
| |and
逻辑与
| 例如: {% if product.title == "Awesome Shoes" %} These shoes are awesome! {% endif %} 可以在一个标记(tag)中使用多个操作符: {% if product.type == "Shirt" or product.type == "Shoes" %} This is a shirt or a pair of shoes. {% endif %} ## contains(包含) `contains` 用于检查在一个字符串中是否存在某个子串。 {% if product.title contains 'Pack' %} This product's title contains the word Pack. {% endif %} `contains` 还可以用于检查一个字符串数组中是否存在某个字符串。 {% if product.tags contains 'Hello' %} This product has been tagged with 'Hello'. {% endif %} `contains` 只能用于搜索字符串。你不能将其用于从一个对象数组中检查是否存在某个对象。 --- URL: https://dev.baklib.cn/liquid/filters/append Updated: 2025-01-02 ## 标题 append ## 内容 将两个字符串拼接起来并返回拼接之后的值。 输入 {{ "/my/fancy/url" | append: ".html" }} 输出 /my/fancy/url.html `append` 同样能够作用于变量: 输入 {% assign filename = "/index.html" %} {{ "website.com" | append: filename }} 输出 website.com/index.html --- URL: https://dev.baklib.cn/api/b59c2 Updated: 2025-08-12 ## 标题 📢 接口更新声明 · 2025 年 8 月 12日 ## 内容 ``` --- ### API 更新文档 — `GET /api/v1/sites/:site_id/pages` #### 变更内容 ##### 1. 新增参数 `full_path_in` * **说明**:支持批量查询多个页面数据,不超过 50 个 `full_path`。 * **格式**:多个路径以逗号分隔,如 `/page1,/page1/page3,/page2` * **示例**: ``` GET /api/v1/sites/123/pages?full_path_in=/page1,/page1/page3,/page2 ``` ##### 2. 新增参数 `fields[pages]` * **说明**:指定返回的页面字段,支持多字段和嵌套字段。列表和详情可用 * **格式**:字段用逗号分隔,如 `full_path, slug ,settings.thumb_url,template_variables.title`。需要settings或者template_variables的字段需要同时传递include_details为true * **示例**: ``` GET /api/v1/sites/123/pages?fields[pages]=name,full_path,slug ``` --- ##### 3. 新增缓存支持 * **说明**: * 新增通过添加请求头 `FROM_CACHE: y` 使用缓存功能。 * 若请求携带此请求头且缓存存在,则直接返回缓存结果,无需重新计算。 * 缓存 key 由当前用户和请求参数组成,确保不同用户和请求参数独立缓存。 * **使用示例**: ```bash curl -H "FROM_CACHE: y" http://your.api/v1/sites/123/pages?full_path_in=/page1 ``` --- ##### 4. 新增 Webhook 支持 * **用途**:知识库设置,站点设置,文章内容变更时推送通知。 * **事件示例**: * `site_pages_events` * `site_settings_events` * **示例负载**: ```json { "site_id":462, "name":"【官网】探码科技", "hook_time":1754994215516, "event_name":"site_pages_events", "pages_updated_at":"2025-08-12T18:23:35.514+08:00" } { "site_id":462, "name":"【官网】探码科技", "hook_time":1754994929529, "event_name":"site_settings_events", "settings_updated_at":"2025-08-12T18:35:29.521+08:00" } ``` --- ##### 5. 修复 * **验证码自动失效**: * 验证码错误输入超过 5 次后,验证码自动失效,需重新获取。 * **翻页重复问题**: * 修复接口分页返回时,存在页面重复的 Bug,保证每页数据唯一且正确。 ``` --- URL: https://dev.baklib.cn/liquid/e1712/246f4 Updated: 2025-09-12 ## 标题 动态表单 - select、radio input 数据引用 ## 内容 当select表单需要使用其他页面的用户输入值作为当前 表达的候选值时,可以通过使用 `choices_from`key 引用其他数据源作为候选值。 使用时原 `choices` 参数改为 `choices_from`。以下为 choices\_from 可选值: 1. `$self.[setting_key]` 从当前页面获取动态表单的值,作为 choices 数据 2. `$index.[setting_key]` 从首页页面获取动态表单的值,作为 choices 数据 3. `$parent.[setting_key]` 从当前页面的上级获取动态表单的值,作为 choices 数据 4. `$site.[setting_key]` 从站点(settings\_schema.json)获取动态表单的值,作为 choices 数据 5. `$site_user_group` 从站点用户组获取数据 被引用的数据返回值必须为 数组 或 textarea input 的输出值 ##### **示例**: # $self.[setting_key] { "id": "keywords", "type": "radio", "choices_from": "$self.keywords_options" "label": "关键词", "info": "从当前页面指定的关键词中选择" } # $index.[setting_key] { "id": "keywords", "type": "radio", "choices_from": "$index.keywords_options" "label": "关键词", "info": "从首页页面指定的关键词中选择" } # $parent.[setting_key] { "id": "keywords", "type": "radio", "choices_from": "$parent.keywords_options" "label": "关键词", "info": "从当前页面的上级指定的关键词中选择" } # $site.[setting_key] { "id": "city", "type": "radio", "choices_from": "$site.cities", "label": "所在城市" "info": "从首页设置城市选择" } # $site_user_group { "id": "user_group_ids", "type": "select", "choices_from": "$site_user_group", "multiple": true, "label": "用户组" } # --- URL: https://dev.baklib.cn/liquid/filters Updated: 2025-01-02 ## 标题 函数(Filters) ## 内容 函数包含abs, append, at\_least, at\_most, capitalize, ceil, compact等一些具体的实用方法,具体教程见:{{ 'generic.search' | t }} {% if search.tag %} {{ search.tag.name }} {% endif %} {% if search.keywords %} {{ search.keywords }} {% endif %}
{% endif %}{# page.settings.content | strip_html | highlight: search.keywords } {{ page.highlighted_search_content }}
{{ link.url }}
Property
|Description
|Returns
| | --- | --- | --- | |length
The total number of iterations in the loop.
|number
parentloop
The parent forloop object. If the current for loop isn’t nested inside another for loop, then nil is returned.
forloop
index
The 1-based index of the current iteration.
|number
index0
The 0-based index of the current iteration.
|number
rindex
The 1-based index of the current iteration, in reverse order.
|number
rindex0
The 0-based index of the current iteration, in reverse order.
|number
first
Returns true if the current iteration is the first. Returns false if not.
boolean
last
Returns true if the current iteration is the last. Returns false if not.
boolean
| Cool Shirt | Alien Poster | Batman Poster | Bullseye Shirt | Another Classic Vinyl | Awesome Jeans |
| Cool Shirt | Alien Poster |
| Batman Poster | Bullseye Shirt |
| Another Classic Vinyl | Awesome Jeans |
|
真值(truthy)
|假值(falsy)
| | --- | --- | --- | |true
|•
|| |
false
||
•
| |nil
||
•
| |string
|•
|| |
empty string
|•
|| |
0
|•
|| |
integer
|•
|| |
float
|•
|| |
array
|•
|| |
empty array
|•
|| |
page
|•
|| |
EmptyDrop
|•
|| [1]: https://liquid.bootcss.com/basics/truthy-and-falsy/#truthy [2]: https://liquid.bootcss.com/basics/truthy-and-falsy/#falsy [3]: https://liquid.bootcss.com/basics/truthy-and-falsy/#summary [4]: https://liquid.bootcss.com/basics/types/#string --- URL: https://dev.baklib.cn/liquid/filters/at-least Updated: 2025-01-02 ## 标题 at_least ## 内容 将数字限制在最小值。 输入 {{ 4 | at_least: 5 }} 输出 5 输入 {{ 4 | at_least: 3 }} 输出 4 --- URL: https://dev.baklib.cn/guide/git Updated: 2025-01-13 ## 标题 通过 git 安装模板 ## 内容 进入【管理】--【组织模板】,在组织模板中,选择 git 安装外部模板: > Baklib 的 git 仓库托管在: > > > gitee: [https://gitee.com/organizations/baklib/projects][1] > > > github: [https://github.com/tanmer][2]  安装完组织模板以后,进入【市场】选择【组织模板】即可找到,点击并安装应用。  [1]: https://gitee.com/organizations/baklib/projects [2]: https://github.com/tanmer --- URL: https://dev.baklib.cn/api/3d3bb Updated: 2025-08-18 ## 标题 📢 接口更新声明 · 2025 年 8 月 18日 ## 内容 ``` ### API 更新文档 — `GET /api/v1/sites/:site_id/pages` #### 变更内容 ### 1. `full_path_in` 参数 * 当 **未传递其他排序参数**(`sort_by`)时,查询结果将 **按照传入的 `full_path_in` 顺序返回**。 * 示例: ```json ?full_path_in=a/b/c, a/d/e ``` 返回结果的顺序将与传入的 `full_path_in` 顺序一致。 --- ### 2. 新增排序参数:`sort_by=position_tree` * 新增支持 **目录结构顺序** 排序。 * 使用方式: ``` ?sort_by=position_tree ``` * **排序规则** 1. 页面顺序由 **父页面链路(祖先路径 + 自身 position)** 决定; 2. 父页面在前 → 其子页面一定整体排在前面; 3. 同一父页面下,子页面按自身 `position` 排序; 4. 保证树形目录结构的完整性。 #### 示例 目录结构(含 position): ``` A (pos=1) ├─ A1 (pos=2) └─ A2 (pos=3) B (pos=2) ├─ B1 (pos=1) │ ├─ B1a (pos=1) │ └─ B1b (pos=2) └─ B2 (pos=2) ``` 排序结果: ``` A, A1, A2, B, B1, B1a, B1b, B2 ``` 解释: * 虽然 **B1 (pos=1)** 小于 **A1 (pos=2)**,但由于 `B` 在 `A` 后面,B1 也必须排在 A 之后; * B1a / B1b 的排序,受制于父页面 B1 的顺序。 --- ### 3. 全文检索(`keywords` 参数)说明 * 当使用 `keywords` 参数进行全文检索时: * **不再执行 `full_path_in` 排序或 `position_tree` 排序**。 * 查询结果只会按照 **搜索相关度(pg\_rank 值)** 排序,确保最相关的结果优先。 --- ### 4. API 缓存说明 #### HTTP Header参数 * **`FROM_CACHE`** * 用于开启缓存,并设置缓存的唯一标识。 * 如果不设置,API 将不启用缓存。 * 修改这个值,即可刷新缓存,旧的缓存依然存在,过期自动清除。 * **`FROM_CACHE_TTL`** * 设置 API 缓存过期时间(单位:秒)。 * 默认值为 **7200 秒(2 小时)**。 * API 缓存时间是 `FROM_CACHE_TTL + 10分钟` 。 --- #### 使用示例 ```bash # 开启缓存,并设置缓存唯一标识 FROM_CACHE=version20250818 # 设置 API 缓存过期时间为 300 秒(默认 7200 秒) FROM_CACHE_TTL=300 ``` 返回的内容过期时间为: ``` FROM_CACHE_TTL + 600 秒 # 示例:300 + 600 = 900 秒 ``` --- #### 清除缓存 通过修改 `FROM_CACHE` 的值即可刷新缓存,例如: ```bash # 原先 FROM_CACHE=version20250818 # 刷新缓存 FROM_CACHE=version20250819 ``` #### 4.1 缓存命中信息(响应 Header) 仅在 **`sites/:id/pages` 接口** 且开启缓存时,响应中会返回以下两个 Header: * `X-Baklib-Cache` → `MISS` 或 `HIT` * `Age` → 缓存存在时间(单位:秒) 示例: ```http X-Baklib-Cache: HIT Age: 120 ``` 说明:该请求命中缓存,缓存已存在 **120 秒**。 ### 5 资源 URL 过期时间控制(请求 Header) * **`DAM_URL_TTL`**:资源 URL 的生存时间(秒),**最高优先级**。 * **`DAM_URL_TTL_DELAY_AFTER_CACHE`**:资源 URL 在**缓存过期后**的额外生存时间(秒)。 * **`DAM_URL_TTL_DELAY_AFTER_CACHE`** 依赖 **`FROM_CACHE_TTL`**,只有在设置了 `FROM_CACHE_TTL` 的情况下才会生效。 #### 5.1 过期时间优先级与计算 资源 URL 的最终过期时间按以下优先级确定: 1. 若设置 **`DAM_URL_TTL`**: ``` URL 过期时间 = DAM_URL_TTL ``` 2. 否则,若同时设置 **`FROM_CACHE_TTL`** 和 **`DAM_URL_TTL_DELAY_AFTER_CACHE`**: ``` URL 过期时间 = FROM_CACHE_TTL + DAM_URL_TTL_DELAY_AFTER_CACHE ``` 3. 否则,若仅设置 **`FROM_CACHE_TTL`**: ``` URL 过期时间 = FROM_CACHE_TTL + 600(10 分钟) ``` 4. 仅开启缓存,未设置其他参数: ``` URL 过期时间 = 默认FROM_CACHE_TTL(2小时) + 600(10 分钟) ``` #### 5.2 使用示例 ```bash # 直接指定 URL 过期时间为 1800 秒(最高优先级) DAM_URL_TTL=1800 # 缓存 300 秒,缓存过期后希望 URL 额外存活 600 秒 FROM_CACHE_TTL=300 DAM_URL_TTL_DELAY_AFTER_CACHE=600 # 实际 URL 过期时间 = 300 + 600 = 900 秒 ``` ``` --- URL: https://dev.baklib.cn/liquid/e1712/5a64b Updated: 2026-03-02 ## 标题 批量创建页面功能配置指南 ## 内容 ``` ## 概述 批量创建页面功能允许模板定义一个专门的界面,让用户能够批量导入/创建页面。这个功能通过在模板的 `schema` 中配置 `batch_create_url` 来实现。 使站点在管理端中可以按需提供批量创建页面的功能。 ## 工作流程 ### 系统交互流程 ``` 1. 用户在页面管理界面中点击"批量创建"按钮 ↓ 2. 系统获取该页面的模板及其子模板信息 ↓ 3. 如果子模板的 schema 中配置了 batch_create_url,则显示批量创建选项 ↓ 4. 用户点击某个模板的批量创建选项 ↓ 5. 系统生成包含认证信息的 batch_create_url 并在 iframe 中打开 ↓ 6. 用户在 iframe 中进行批量导入操作 ↓ 7. iframe 中的页面通过 API 调用创建页面 ``` ## 配置步骤 ### 1. 在模板 Schema 中添加 `batch_create_url` 在你的 `.liquid` 模板文件中,在 `{% schema %}` 部分添加 `batch_create_url` 配置: ```liquid {% schema %} { "name": "页面模板名称", "description": "页面模板描述", "batch_create_url": "https://your-import-service.com/batch_import", // 或者 "/s/batch_import"(模版中静态地址) "settings": [ // ... 其他模板设置 ] } {% endschema %} ``` ### 2. `batch_create_url` 的两种形式 #### 2.1 绝对 URL(推荐用于外部服务) ```json { "batch_create_url": "https://external-service.com/batch_import" } ``` 绝对 URL 使用完整的 http/https 地址。系统会自动追加以下查询参数: - `token`: 用户的临时 API token(JWT 格式) - `site_id`: 当前站点 ID - `full_path`: 父页面的完整路径 - `template_name`: 模板名称 - `template_style`: 模板风格 **示例生成的 URL:** ``` https://external-service.com/batch_import? token=JWT+eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE3NzAyOTY1NTh9... &site_id=34 &full_path=%2F80ec12 &template_name=page &template_style=style ``` #### 2.2 相对路径 URL(建议页面构建在模版中静态页面中) ```json { "batch_create_url": "/s/batch_import" } ``` 相对路径会被转换为完整的站点门户 URL。系统会使用站点的门户地址作为基础 URL,并追加相同的查询参数。 **示例生成的 URL:** ``` http://site-demo.baklib.localhost:3000/s/batch_import? token=JWT+eyJhbGciOiJIUzI1NiJ9... &site_id=34 &full_path=%2Fparent &template_name=page &template_style=style ``` ### 3. 完整的模板配置示例 ```liquid {% # 模板的 HTML/Liquid 内容 %} {% schema %} { "name": "数据批量导入页面", "description": "支持批量创建页面的模板", "thumb_url": "images/theme/batch_import_page.png", "batch_create_url": "https://api.example.com/pages/batch_import", "settings": [ { "id": "title", "type": "text", "label": "页面标题" }, { "id": "description", "type": "richtext", "label": "页面描述" }, { "id": "enable_batch_import", "type": "checkbox", "label": "启用批量导入", "default": true } ] } {% endschema %} ``` ## 在批量创建 iframe 中的操作 ### 接收的查询参数 当 iframe 中的页面加载时,会收到以下查询参数: | 参数 | 说明 | 示例 | |------|------|------| | `token` | JWT 格式的 API 认证 token | `JWT eyJhbGciOiJIUzI1NiJ9...` | | `site_id` | 站点的数字 ID | `34` | | `full_path` | 父页面的完整路径(URL 编码) | `%2F80ec12` | | `template_name` | 模板名称 | `page` | | `template_style` | 模板风格 | `style` | ### 调用 API 创建页面 iframe 中的页面可以通过以下 Baklib API 创建新页面: > baklib api接口文档: https://dev.baklib.cn/api#/paths/sites-site_id--pages/post ## 最佳实践 ### 1. 选择合适的 URL 类型 - **外部服务**:使用绝对 URL(完整的 http/https 地址) - **站点内部**:使用相对路径(以 `/` 开头) ### 2. 安全考虑 - 传递给 iframe 的 `token` 是临时 API token,有过期时间限制 - 确保你的批量创建服务在安全的 HTTPS 连接上运行 - 验证 `site_id` 和 `full_path` 参数的有效性 ### 3. 用户体验 - 在模板中明确说明支持批量创建功能 - 在 `batch_create_url` 指向的页面中提供清晰的导入说明 - 实现进度提示和错误处理 ### 4. 模板命名规范 - `template_name`: 模板的基础名称(如 `page`, `article`) - `template_style`: 模板的风格变体(如 `default`, `dark`, `compact`) ## 故障排查 ### 问题:批量创建选项不显示 **可能原因:** - 模板的 schema 中没有配置 `batch_create_url` - `batch_create_url` 值为空或 `null` - 子模板没有正确关联到父模板 **解决方案:** 1. 检查模板文件中的 `schema` 部分 2. 确保 `batch_create_url` 有有效的值 3. 验证模板的 `sub_page_templates` 配置 ### 问题:iframe 加载失败 **可能原因:** - URL 解析错误 - 网络不可达 - CORS 跨域问题 **解决方案:** 1. 检查浏览器控制台的错误信息 2. 验证 URL 是否正确生成 3. 确保批量创建服务正在运行 4. 检查是否配置了适当的 CORS 头 ### 问题:无法创建页面 **可能原因:** - API token 已过期 - 用户权限不足 - API 参数格式错误 **解决方案:** 1. 刷新页面重新获取 token 2. 检查用户是否有页面创建权限 3. 验证 API 请求体格式是否正确 ``` --- URL: https://dev.baklib.cn/overview Updated: 2024-11-28 ## 标题 模板设置 ## 内容 本章节介绍 Baklib 模板开发的入口界面,如何应用到站点中,如何进入低代码编辑器。 --- URL: https://dev.baklib.cn/overview/themes/wiki Updated: 2024-11-17 ## 标题 Wiki: Wiki 主题模板 ## 内容  **模板类型:**wiki **模板名称:** Wiki知识库系统 **应用场景:**用于大型可复用的文档内容管理,基于KB知识库,构建Wiki、Documentation、Help Center等站点。 ## 首页主题风格 首页主题风格有多种形式,可以支持轮播、大图展示、播放视频等。  首页预览  help center 风格  list 风格 ## 页面风格 页面详情主要包含侧边栏导航和页面主体内容本身。  网站的页面预览效果:   完整的页面截图  更换主题颜色预览效果。 --- URL: https://dev.baklib.cn/overview/themes Updated: 2024-07-19 ## 标题 公共模板 ## 内容 公共模板是系统自带的模板样例,这些模板覆盖了不同场景的使用体验,用户可以通过公共模板快速匹配业务需求,以启动相关项目。 --- URL: https://dev.baklib.cn/theme/locales Updated: 2024-07-19 ## 标题 locales/ ## 内容 翻译文件是`json`类型,其中包含一组在整个主题中使用的文本字符串的翻译 客户除了可以编辑在整个主题中重复的单词和短语之外,还允许将站点内容设置翻译成国际商家和客户的多种语言。 ### 定义: { "hello": "你好", } ### 调用: # {{ 'hello' | t }} # {{ 'hello' | t: '你好' }} 默认值: 你好 # {{ 'hello' | t: '你好', locale: 'de' }} 默认值: 你好, 语言:德语, 翻译:Hallo # {{ 'hello' | t, locale: 'de' }} 语言:德语, 翻译:Hallo --- URL: https://dev.baklib.cn/theme/locales/zh-cn-schema-json Updated: 2024-07-19 ## 标题 zh-CN.schema.json ## 内容 { "settings_schema": { "generic": { "name": "站点基本信息设置", "help_center_index_description": "功能丰富的产品知识库样式", "list_index_description": "首页目录列表样式", "header_name": "页头页尾导航菜单", "head_title": "Head HTML 配置", "settings": { "hero_image_url": { "label": "首页背景大图", "info": "用于部分主题首页的背景横幅,建议1900*600px的深色图片" }, "title": { "label": "站点标题" }, "description": { "label": "站点描述" }, "hot_tags": { "label": "热搜关键词(请用英文逗号「,」分隔)" }, "copyright_info": { "label": "备案/版权信息", "default": "蜀ICP备15035023号" }, "company_name": { "label": "公司名称", "default": "Baklib.cn" }, "header_menu_html": { "label": "Header页头导航菜单", "info": "支持HTML标签和TailwindCss样式代码" }, "footer_menu_html": { "label": "Footer页尾导航菜单", "info": "支持HTML标签和TailwindCss样式代码" }, "head_html": { "label": "Head Meta HTML代码", "info": "这部分内容会植入到站点的标签内,请使用标准的 HTML 格式", "placeholder": "" } } }, "page": { "name": "页面", "description": "文档内容页面", "settings": { "description":{ "label": "页面描述" }, "content":{ "label": "内容", "info": "同步自数据源,不可编辑" }, "icon": { "label": "页面图标", "info": "用于显示页面图标,建议1:1比例" }, "tags":{ "label": "标签" } } } } } --- URL: https://dev.baklib.cn/theme/snippets/footer Updated: 2024-07-19 ## 标题 _footer.liquid ## 内容 {% assign screen_width = site.settings.screen_width.value | default: 'max-w-screen-xl' %} --- URL: https://dev.baklib.cn/theme/templates/tag Updated: 2024-07-19 ## 标题 tag.liquid ## 内容 标签页模板,位于: `templaes/tag.liquid` 通常标签页模板主要是将指定的某个标签下的所有页面展示出来,该页面会传人一个变量: `tag `,通过遍历 `tag.pages` 获得标签下所有页面。 通用代码如下:
Class
|Properties
| | --- | --- | |text-wrap
|text-wrap: wrap;
| |text-nowrap
|text-wrap: nowrap;
| |text-balance
|text-wrap: balance;
| |text-pretty
|text-wrap: pretty;
| [1]: https://tailwindcss.com/docs/text-wrap --- URL: https://dev.baklib.cn/liquid/tags/raw Updated: 2025-01-02 ## 标题 原始内容 ## 内容 `raw` 标记临时禁止处理其所包围的代码。如果输出的内容与 Liquid 模板语言有冲突时(例如 Mustache、Handlebars 模板语言)可以避免冲突。 输入 {% raw %} In Handlebars, {{ this }} will be HTML-escaped, but {{{ that }}} will not. {% endraw %} 输出 In Handlebars, {{ this }} will be HTML-escaped, but {{{ that }}} will not. --- URL: https://dev.baklib.cn/liquid/basics/e2a2 Updated: 2025-01-02 ## 标题 数据类型 ## 内容 Liquid 对象的类型可以是以下五种: * [String][1] * [Number][2] * [Boolean][3] * [Nil][4] * [Array][5] 你可以通过 [assign][6] 或 [capture][7] 标记来初始化 Liquid 变量。 ## String(字符串) 将变量的值包裹在单引号或双引号之中就声明了一个字符串: {% assign my_string = "Hello World!" %} ## Number(数字) 数字类型包括浮点数和整数: {% assign my_int = 25 %} {% assign my_float = 39.756 %} ## Boolean(布尔) Booleans 类型只能是 `true` 或 `false`。布尔值千万不能加引号,否则就成为字符串了。 {% assign foo = true %} {% assign bar = false %} ## Nil(空) Nil 是一个特殊的空值,当 Liquid 代码没有可输出的结果时将返回 Nil。他并**不是**由 “nil” 这个三个字符组成的字符串。 在 `if` 条件判断和其他 Liquid 标记(tag)判断语句中,Nil [被当做 false][8] 。 下例中,如果 user 不存在(也就是 `user` 返回 `nil`),Liquid 不输出问候语: {% if user %} Hello {{ user.name }}! {% endif %} 如果 Liquid 标记(tag)或输出返回的是 `nil`,页面上将不会有任何内容。 输入 The current user is {{ user.name }} 输出 The current user is ## Array(数组) 数组能够存储一组任意类型的变量。 ### 访问数组中的项 通过 [迭代标记(iteration tag)][9] 可以访问数组中的所有项。 输入 {% for user in site.users %} {{ user }} {% endfor %} 输出 Tobi Laura Tetsuro Adam ### 访问数组中的特定项 利用方括号 `[` `]` 能够访问数组中的特定项。数组的索引从 0 开始。 输入 {{ site.users[0] }} {{ site.users[1] }} {{ site.users[3] }} 输出 Tobi Laura Adam ### 初始化数组 你无法只通过 Liquid 语法初始化一个数组。 然而,你可以利用 [split][10] 过滤器将一个字符串分割为一个子字符串数组。 [1]: https://liquid.bootcss.com/basics/types/#string [2]: https://liquid.bootcss.com/basics/types/#number [3]: https://liquid.bootcss.com/basics/types/#boolean [4]: https://liquid.bootcss.com/basics/types/#nil [5]: https://liquid.bootcss.com/basics/types/#array [6]: https://liquid.bootcss.com/tags/variable/#assign [7]: https://liquid.bootcss.com/tags/variable/#capture [8]: https://liquid.bootcss.com/basics/truthy-and-falsy [9]: https://liquid.bootcss.com/tags/iteration [10]: https://liquid.bootcss.com/filters/split --- URL: https://dev.baklib.cn/liquid/filters/at-most Updated: 2025-01-02 ## 标题 at_most ## 内容 将数字限制在最大值。 输入 {{ 4 | at_most: 5 }} 输出 4 输入 {{ 4 | at_most: 3 }} 输出 3 --- URL: https://dev.baklib.cn/install/init Updated: 2025-01-13 ## 标题 初始化资源 ## 内容 ## 开发 ```bash npm run dev ``` ### 安装配置TailwindCSS [TailwindCSS官网](https://www.tailwindcss.cn/docs/installation) #### 1.安装Tailwindcss 通过`npm`安装`tailwindcss`,然后创建`tailwind.config.js`配置文件 ```bash npm add -D tailwindcss npx tailwindcss init ``` #### 2.配置模板文件的路径和自定义样式 ```javascript /** @type {import('tailwindcss').Config} */ module.exports = { content: ["./templates/**/*.liquid", "./snippets/**/*.liquid", "./layout/**/*.liquid", "./statics/**/*.liquid"], darkMode: 'class', theme: { extend: { colors: () => { return { slate: { 150: "#E9EEF5" }, ...["primary", "secondary", "accent", "info", "success", "warning"].reduce((map, name) => { return { ...map, [name]: { DEFAULT: `hsl(var(--theme-color-${name}) /这是一段加粗的文本。
``` 输出: ```markdown ## 正文 这是一段**加粗**的文本。 ``` #### 代码类型 Schema 配置: ```json { "id": "script", "type": "code", "label": "脚本代码", "language": "javascript", "to_markdown": true } ``` 输出: ```markdown ## 脚本代码 ```javascript const x = 1; ``` ``` #### 图片选择器 输出 Markdown 图片语法: ```markdown ## 封面图  ``` #### 文件/视频选择器 仅输出 URL 字符串(无 Markdown 包裹): ``` ## 附件 https://portal.example.com/signed-url?expires=... ``` #### 标签选择器 根据标签 IID 输出名称列表: ```markdown ## 标签 技术, 文档, 教程 ``` ## 资源链接有效期配置 资源选择器生成的 URL 有效期默认为 20 分钟,可通过修改常量调整: ```ruby # app/models/page/to_markdown.rb PORTAL_URL_EXPIRES_IN = 20.minutes ``` ``` --- URL: https://dev.baklib.cn/liquid Updated: 2024-11-28 ## 标题 Liquid 语法 ## 内容 Baklib 的主题模板是通过 Liquid 模板语言开发的,在熟悉主题模板开发之前,需要了解 Liquid 基本语法。 👏 Liquid 是由 Shopify 创建并用 Ruby 编写的开源模板语言。它是 Shopify(全球最大的独立电商平台) 主题的支柱,用于在店面加载动态内容。 Liquid 自 2006 年起就在 Shopify 投入生产,现在也被许多其他托管 Web 应用程序使用。 **教程:** [https://shopify.github.io/liquid/][1] > ***请直接参考官方教程,若没有特殊说明,Baklib 遵循 Liquid 官方教程版本同步。*** [1]: https://shopify.github.io/liquid/ --- URL: https://dev.baklib.cn/overview/themes/daisy-wiki Updated: 2024-11-17 ## 标题 Wiki: Daisy Wiki ## 内容  **模板类型:**wiki **模板名称:** Daisy Wiki **应用场景:**内置基于 DaisyUI 构建的多风格主题、内容驱动型知识库门户。用于大型可复用的文档内容管理,基于KB知识库,构建Wiki、Documentation、Help Center等站点。 ## 首页主题风格 首页主题风格支持 12 种个性化切换。  主题切换  help center 风格首页 ## 页面风格 页面详情主要包含侧边栏导航和页面主体内容本身。 栏目页面:  详情页面:  得益于 Daisy UI 的丰富组件库,可以自定义构建各种效果的页面块布局。  --- URL: https://dev.baklib.cn/theme/snippets Updated: 2024-07-19 ## 标题 snippets/ ## 内容 snippets 目录中包含自定义的可重用模板片段,比如页头、页脚、面包屑、导航、广告等页面片段。 ### **定义** 创建一个文件: snippets/\_footer.liquid ### **调用** 用 `render` 方法在 `layouts/`和`templates/`的模板文件中引用文件: {% render 'footer' %} 下面是一些常见的页面片段: --- URL: https://dev.baklib.cn/theme/templates/robots Updated: 2024-07-19 ## 标题 robots.txt.liquid ## 内容 模板 `robots.txt.liquid` 呈现 `robots.txt` 托管在 `/robots.txt` URL 上的文件。 该文件 `robots.txt` 告诉搜索引擎哪些页面可以或不能在网站上抓取。它包含执行此操作的规则组,每个组有三个主要组件: * 用户代理,用于记录规则组应用于哪个爬网程序。例如, `adsbot-google` . * 规则本身,用于记录爬网程序可以访问或无法访问的特定 URL。 * 可选的站点地图网址。 `baklib`默认情况下会生成一个 `robots.txt` 文件,该文件适用于大多数站点,因此默认情况下此模板不包含在任何主题中。 通用代码: User-Agent: * Disallow: --- URL: https://dev.baklib.cn/faqs/31b7 Updated: 2024-11-28 ## 标题 如何添加暗黑模式: Dark mode ## 内容 Baklib 的模板都默认带有暗黑模式,暗黑模式的实现方法如下。 在 src/main.js 中: import ThemeController from "./theme_controller" const application = Application.start() window.Stimulus = application application.register('theme', ThemeController) 在theme\_contrller.js中: import { Controller } from "@hotwired/stimulus"; //自动跟随系统: window.matchMedia('(prefers-color-scheme: dark)').matches export default class extends Controller { static targets = ["checkbox"]; connect() { const dark = localStorage.getItem("dark-mode"); if (dark && dark == 'true' || window.matchMedia('(prefers-color-scheme: dark)').matches) { document.documentElement.classList.add("dark"); this.checkboxTarget.checked = true; } else { document.documentElement.classList.remove("dark"); this.checkboxTarget.checked = false; } } toggle() { const checkbox = this.checkboxTarget; const isDarkMode = checkbox.checked; if (isDarkMode) { document.documentElement.classList.add("dark"); localStorage.setItem("dark-mode", true); } else { document.documentElement.classList.remove("dark"); localStorage.setItem("dark-mode", false); } } } 接下来在网页中添加 light/dark 的切换开关:settings_type(表单类型)
|数据类型
| | --- | --- | |checkbox
|boolean
| |color, color_background, font_picker, image_picker, link, radio, select, tag_picker, text, video_picker
|multiple = true ? array : string
| |date
|date
| |html, richtext, textarea
|text
| |number, range
|float
| ## **5. where - 页面属性** ### **5.1 页面属性筛选逻辑** 1. **字段格式**:字段名由 `属性名_操作符` 构成(如:`visits_count_gt`, \'created\_at\_lteq\')。 2. **数据类型限制操作符**:每个字段根据数据类型限制支持的操作符。 3. **支持 AND / OR 组合查询**:可组合多条件查询。 4. **可筛选字段**:仅下面列出的字段支持筛选。 ### **5.2 可用作筛选的页面属性** 页面属性是指页面自身的属性,可用于筛选。支持的页面属性包括: |属性名
|说明
|数据类型
| | --- | --- | --- | |name
|页面名称(计算后实际展示的值)
|string
| |visits_count
|访问次数
|integer
| |full_path
|完整路径
|string
| |template_name
|模板名称
|string
| |template_style
|模板样式
|string
| |updated_at
|页面更新时间
|datetime
| |created_at
|页面创建时间
|datetime
| ## **6. 筛选操作符表及其解释** ``` | 操作符 | 含义 | 适用类型 | 例如 | |--------|------|----------|------| | `eq` | 等于 | 所有类型 | `"name_eq": "产品"` | | `not_eq` | 不等于 | 所有类型 | `"name_not_eq": "产品"` | | `lt` | 小于 | 数值、日期 | `"visits_count_lt": 100` | | `gt` | 大于 | 数值、日期 | `"visits_count_gt": 100` | | `lteq` | 小于等于 | 数值、日期 | `"created_at_lteq": "2023-01-01"` | | `gteq` | 大于等于 | 数值、日期 | `"created_at_gteq": "2023-01-01"` | | `cont` | 包含(区分大小写) | 字符串 | `"title_cont": "关键词"` | | `i_cont` | 包含(忽略大小写) | 字符串 | `"title_i_cont": "关键词"` | | `not_cont` | 不包含(区分大小写) | 字符串 | `"title_not_cont": "关键词"` | | `not_i_cont` | 不包含(忽略大小写) | 字符串 | `"title_not_i_cont": "关键词"` | | `start` | 以...开头 | 字符串 | `"name_start": "产品"` | | `not_start` | 不以...开头 | 字符串 | `"name_not_start": "产品"` | | `end` | 以...结尾 | 字符串 | `"name_end": "产品"` | | `not_end` | 不以...结尾 | 字符串 | `"name_not_end": "产品"` | | `matches` | 正则匹配 | 字符串 | `"name_matches": "^产品.*"` | | `does_not_match` | 正则不匹配 | 字符串 | `"name_does_not_match": "^产品.*"` | | `matches_any` | 任意正则匹配 | 字符串 | `"name_matches_any": ["^产品.*", ".*服务$"]` | | `matches_all` | 所有正则匹配 | 字符串 | `"name_matches_all": ["^产品.*", ".*服务$"]` | | `does_not_match_any` | 任意正则不匹配 | 字符串 | `"name_does_not_match_any": ["^产品.*", ".*服务$"]` | | `does_not_match_all` | 所有正则不匹配 | 字符串 | `"name_does_not_match_all": ["^产品.*", ".*服务$"]` | | `in` | 在集合中 | 字符串 | `"name_in": ["产品1", "产品2"]` | | `not_in` | 不在集合中 | 字符串 | `"name_not_in": ["产品1", "产品2"]` | | `start_any` | 任意以...开头 | 字符串 | `"name_start_any": ["产品", "服务"]` | | `start_all` | 所有以...开头 | 字符串 | `"name_start_all": ["产品", "服务"]` | | `not_start_any` | 任意不以...开头 | 字符串 | `"name_not_start_any": ["产品", "服务"]` | | `not_start_all` | 所有不以...开头 | 字符串 | `"name_not_start_all": ["产品", "服务"]` | | `end_any` | 任意以...结尾 | 字符串 | `"name_end_any": ["产品", "服务"]` | | `end_all` | 所有以...结尾 | 字符串 | `"name_end_all": ["产品", "服务"]` | | `not_end_any` | 任意不以...结尾 | 字符串 | `"name_not_end_any": ["产品", "服务"]` | | `not_end_all` | 所有不以...结尾 | 字符串 | `"name_not_end_all": ["产品", "服务"]` | | `cont_any` | 任意包含(区分大小写) | 字符串 | `"name_cont_any": ["产品", "服务"]` | | `cont_all` | 所有包含(区分大小写) | 字符串 | `"name_cont_all": ["产品", "服务"]` | | `not_cont_any` | 任意不包含(区分大小写) | 字符串 | `"name_not_cont_any": ["产品", "服务"]` | | `not_cont_all` | 所有不包含(区分大小写) | 字符串 | `"name_not_cont_all": ["产品", "服务"]` | | `i_cont_any` | 任意包含(忽略大小写) | 字符串 | `"name_i_cont_any": ["产品", "服务"]` | | `i_cont_all` | 所有包含(忽略大小写) | 字符串 | `"name_i_cont_all": ["产品", "服务"]` | | `not_i_cont_any` | 任意不包含(忽略大小写) | 字符串 | `"name_not_i_cont_any": ["产品", "服务"]` | | `not_i_cont_all` | 所有不包含(忽略大小写) | 字符串 | `"name_not_i_cont_all": ["产品", "服务"]` | | `true` | 为真 | 布尔值 | `"is_active_true": true` | | `false` | 为假 | 布尔值 | `"is_active_false": false` | | `array_cont_all` | 包含所有指定值 | 数组 | `"array_cont_all": ["热门", "促销"]` | | `not_array_cont_all` | 不包含所有指定值 | 数组 | `"not_array_cont_all": ["热门", "促销"]` | | `array_cont_any` | 包含任一指定值 | 数组 | `"array_cont_any": ["热门", "促销"]` | | `not_array_cont_any` | 不包含任一指定值 | 数组 | `"not_array_cont_any": ["热门", "促销"]` | | `array_equals` | 数组完全相等 | 数组 | `"array_equals": ["热门", "促销"]` | | `not_array_equals` | 数组不完全相等 | 数组 | `"not_array_equals": ["热门", "促销"]` | ``` ### **7. 数据类型可允许的操作符** |数据类型
|支持的操作符
| | --- | --- | |boolean
|true, false, eq
string
|eq not_eq matches does_not_match matches_any matches_all does_not_match_any does_not_match_all in not_in start not_start start_any start_all not_start_any not_start_all end not_end end_any end_all not_end_any not_end_all cont cont_any cont_all not_cont not_cont_any not_cont_all i_cont i_cont_any i_cont_all not_i_cont not_i_cont_any not_i_cont_all
text
|i_cont cont not_i_cont not_cont eq not_eq start not_start end not_end
date / datetime
|eq, not_eq, lt, gt, lteq, gteq
float / integer
|eq, not_eq, lt, gt, lteq, gteq
array
|array_cont_all, not_array_cont_all, array_cont_any, not_array_cont_any, array_equals, not_array_equals
参数名
|描述
|类型
|默认值
|示例
| | --- | --- | --- | --- | --- | |collection_name
|要搜索的pages数据集合
|PagesDrop
| |site.pages 站点下所有页面进行检索
page.children 当前页面下的仅下级页面
page.pages 当前页面下的全部页面
keywords
|搜索关键词
|字符串或变量
| | | |by_user
|标记是否为用户检索,若为true将自动记录用户检索记录与统计数据
Boolean
|true
| | ## **3. 搜索结果可用属性** 在 `{% search ... %}` 和 `{% endsearch %}` 包裹的内容中,可通过 `search` 对象获取以下参数: * `search.pages` 搜索结果页面集合,可用于遍历。 * `search.keywords` 本次搜索的关键词。 * `search.extends` 额外扩展信息(如有)。 ## **4. 直达跳转(自动处理)** 如果搜索结果为直达,会自动跳转到目标页面。 > 由站点页面管理,搜索记录/自定义搜索结果 中配置 #### ## **5. 设置模板可用于分词检索的动态变量** 在模板文件的 settings\_schema 中添加 searchable: true {% schema %} { "name": "Help Center", "settings": [ { "id": "description_en", "type": "textarea", "label": "英文描述", "searchable": true # 开启后,创建的页面中填写此值的,在前端可直接分词搜索 } ] } {% endschema %} ## **6. 示例** - 目标:在某栏目页面中实现筛选、搜索功能 - 可筛选页面动态字段(由模版settings中自行开启): tags (array[tag])、 category(string)) - 可搜索页面内容:页面标题、内容等, 由url中获取params 提供的关键词进行搜索 - 实现方案:通过query tag + search tag,共同处理 - 页面模版中:templates/articles_channel.liquid {% query pages1 from site.pages %} { "where": { "tags_array_cont_any": ["faq", "help"] "category_eq": "会议" } } {% endquery %} {% search pages1, keywords: params[:q] %}{{ page.highlighted_search_content }}
页面内容
``` ## 实际应用场景 ### 场景 1:Turbo Stream 表单提交 表单提交后,使用 Turbo Stream 更新页面内容,显示验证错误或成功消息。 ```liquid {% response_type "turbo_stream" %} {% layout none %} {%# 替换表单,显示验证错误 %}字段
|说明
|是否必填
|示例
| | --- | --- | --- | --- | |language
站点语言(由模板config/settings_schema.json 中 theme_languages 的配置值提供可用值,从中选择一项)
|否
|'zh-CN', 'en', 'zh-TW'
time_zone
时区
|否
|Beijing
favicon
网站图标
|否
|资源地址;模板内images/下的图片或远程可访问的图片地址
| |settings
settings_schema 动态表单配置,依据 config/settings_schema.json中settings 提供的可配置项进行设置
否
| | ### 3.2 `pages` 页面结构 用于初始创建站点页面,支持多层级子页面创建。 #### 示例(YAML) pages: title: "首页" slug: "index" template_name: "page" settings: hero_image_url: "images/home-banner.png" search_hot_keywords: "安装\n使用指南\nFAQ" children: - name: "product_index-1" template_name: "product_index" settings: textarea: "----描述" icon: "images/logo.svg" thumb_image_url: "https://example.com/thumb.png" content_html: "preset:footer_nav_links2.html" - name: "product_index-2" slug: "test2" template_name: "product_index" settings: textarea: "----描述2" icon: "images/logo.svg" thumb_image_url: "https://example.com/thumb2.png" content_html: "preset:footer_nav_links2.html" #### 可配置属性 |字段
|说明
|是否必填
|示例
| | --- | --- | --- | --- | |name
页面标题
|必填
|"product_index-1"
slug
页面路径
|否
|"index", "guide"
template_name
页面模板名称
|必填
|"page", "product_index"
template_style
页面头图
| |当需要使用页面模板类似格式为templates/index.preview.liquid 时,此项填写 preview
settings
由当前页面指定的页面模板中schema.settings来配置;以schema.settings的id为key,值为value的形式
值的数据类型请根据动态表单的类型
children
下级页面的数据(数组格式)
| | | ## 4. 使用 `preset:` 引用复杂格式内容 当需要插入复杂内容时,可以使用 `preset:`: * 默认仅从 `templates/presets/` 目录加载 * 内容会完整替换字段值 #### 示例 content_html: "preset:faq.html" ## 5. 资源引用 初始数据配置中依据站点字段类型、页面字段类型或动态表单的类型来决定是否需要使用资源 在 `site` 或 `pages` 配置中,常见的字段值支持以下几类资源引用方式: |类型
|格式
|示例
|说明
| | --- | --- | --- | --- | |模板内置图片
|"images/..."
"images/logo.png"
引用模板 assets/ 目录下的文件
远程资源
|"http://..." 或 "https://..."
"https://example.com/banner.png"
使用外部 URL
| |预设内容
|"preset:..."
"preset:faq.md"
引用 templates/presets/ 下的文件内容,适合长文本/富文本