# EasyShortCode **Repository Path**: ymz316/easy-short-code ## Basic Information - **Project Name**: EasyShortCode - **Description**: 基于typecho的短代码插件 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-14 - **Last Updated**: 2026-07-14 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # EasyShortCode 短代码插件 Typecho 短代码插件,在文章/页面中解析 `[tag]...[/tag]` 语法,共 **20 个内置短代码**,附带后台编辑器工具栏和弹窗配置。 ## 目录 - [实现原理](#实现原理) - [安装与配置](#安装与配置) - [编辑器工具栏](#编辑器工具栏) - [短代码列表](#短代码列表) - [内容排版](#内容排版) - [媒体](#媒体) - [相册](#相册) - [引用](#引用) - [其他](#其他) - [扩展开发](#扩展开发) - [样式自定义](#样式自定义) - [安全说明](#安全说明) - [文件结构](#文件结构) - [许可](#许可) ## 实现原理 ### 解析流程 ``` 文章 Markdown 源码 │ ▼ Typecho Markdown 解析 │ ▼ contentEx 钩子 → EasyShortCode::parse() │ ├─ 按注册顺序遍历 20 个短代码的正则模式 ├─ 成对标签:[tag attr="val"]content[/tag] ├─ 自闭合标签:[tag attr="val"] ├─ [raw] 最先匹配,防止内嵌短代码被二次解析 └─ 块级元素前后
自动清理 │ ▼ 最终 HTML 输出 ``` ### 核心机制 **钩子系统** | 钩子 | 用途 | |------|------| | `Widget_Abstract_Contents::contentEx` | 文章内容短代码解析 | | `Widget_Archive::handleInit` | 加载 Parser.php | | `Widget_Archive::footer` | 注入 CSS + 前端 JS | | `admin/header.php::header` | 注入编辑器 CSS | | `admin/write-post.php::bottom` | 注入编辑器工具栏 JS | | `admin/write-page.php::bottom` | 同上(页面编辑) | **正则引擎** - 每个短代码生成两个模式:成对 + 自闭合 - `\[` 转义支持:写 `\[tag]` 不被解析 - 属性用 `key="val"` 格式,大小写不敏感 - 解析失败静默回退,不破坏页面 - 模式按标签名缓存,避免重复编译 **XSS 防护** - 属性值:`htmlspecialchars($val, ENT_QUOTES, 'UTF-8')` - 枚举值:白名单校验,不在白名单则回退默认值 - body 内容:视为受信 HTML,不转义保留 `
`、`` 等 ## 安装与配置 . 将 `EasyShortCode` 放入 `usr/plugins/` . 后台 → 控制台 → 插件 → 启用 **EasyShortCode** . 点击 **设置** 进行配置 | 配置 | 默认值 | 说明 | |------|--------|------| | 隐藏块样式 | 折叠(details/summary) | `[hide]` 的展示方式 | | 按钮 CSS 类名 | `esc-btn` | 便于主题覆盖 | ## 编辑器工具栏 启用后,文章/页面编辑区上方自动注入短代码按钮。有弹窗配置的按钮(标 `…`)点击弹出表单,其余直接插入模板。 ``` [按钮…] [提示框…] [备注] [隐藏块…] | [图片…] [视频…] [聊天…] [文件…] [音频…] | [进度条…] [标签页] [时间线] [自适应相册] [瀑布流相册] [横向滚动] [网格相册…] [网格跨度] | [站内文章…] [站外文章…] | [原样输出] ``` ## 短代码列表 ### 内容排版 #### 按钮 `[button]` / `[btn]` ``` [button url="https://x.com" type="primary" blank="true"]文字[/button] ``` | 属性 | 默认值 | 说明 | |------|--------|------| | `url` | `#` | 链接 | | `type` | `primary` | primary / success / warning / danger / secondary | | `blank` | `false` | 新窗口打开(含 `rel="noopener noreferrer"`) | #### 提示框 `[alert]` ``` [alert type="info"]内容(支持 HTML)[/alert] ``` | 属性 | 默认值 | 说明 | |------|--------|------| | `type` | `info` | info / success / warning / error | #### 备注 `[tip]` / `[notice]` ``` [tip]备注内容[/tip] [notice type="warning"]警告[/notice] ``` 属性同 `[alert]`。 #### 隐藏块 `[hide]` ``` [hide title="点击展开"]隐藏内容[/hide] ``` | 属性 | 默认值 | 说明 | |------|--------|------| | `title` | 点击展开 | 折叠模式标题 | 两种样式(插件设置中切换):折叠展开 / 模糊遮挡(hover 显示)。 #### 进度条 `[progress]` ``` [progress value="85" color="green" sub="熟练掌握"]Python[/progress] ``` | 属性 | 默认值 | 说明 | |------|--------|------| | body | - | 名称(header 左侧) | | `value` | 50 | 百分比 0–100 | | `color` | blue | blue / green / red / yellow / purple / orange | | `sub` | - | 底部描述 | | `striped` | true | 条纹动画 | | `animate` | false | 脉冲呼吸效果 | #### 标签页 `[tabs]` ``` [tabs] [tab title="标签1"]内容1[/tab] [tab title="标签2"]内容2[/tab] [/tabs] ``` 纯 CSS radio 实现,第一个默认选中,内容支持 HTML。 #### 时间线 `[timeline]` ``` [timeline] [item date="2024-01"]事件[/item] [item date="2024-06"]事件[/item] [/timeline] ``` 竖线 + 圆点标记样式,`[item]` 无数量限制。 --- ### 媒体 #### 单图片 `[img]` ``` [img src="https://x.com/photo.jpg"]标题[/img] ``` | 属性 | 默认值 | 说明 | |------|--------|------| | `src` | **必填** | 图片 URL | | body | - | 标题(显示在图片底部渐变遮罩上) | #### 视频 `[video]` ``` [video type="video/mp4"]https://x.com/v.mp4[/video] ``` | 属性 | 默认值 | 说明 | |------|--------|------| | `type` | video/mp4 | MIME 类型 | | `preload` | auto | auto / metadata / none | #### 音频 `[audio]` ``` [audio src="https://x.com/song.mp3" title="歌名"][/audio] ``` | 属性 | 默认值 | 说明 | |------|--------|------| | `src` | **必填** | 音频 URL | | `title` | - | 标题 | #### 聊天气泡 `[chat]` ``` [chat author="我" type="sent" email="xx@qq.com"] 消息内容(支持 HTML) [/chat] ``` | 属性 | 默认值 | 说明 | |------|--------|------| | `author` | 我 | 名称 | | `type` | sent | sent(右蓝)/ received(左灰) | | `email` | - | QQ→QQ头像,其他→Cravatar | | `imageurl` | - | 自定义头像,优先于 email | | `todate` | 当前 | 时间戳 | #### 文件下载 `[file]` ``` [file url="https://x.com/doc.pdf"]文档.pdf[/file] ``` --- ### 相册 #### 自适应相册 `[album-auto]` ``` [album-auto] [img src="1.jpg"]图1[/img] [img src="2.jpg"]图2[/img] [/album-auto] ``` CSS Grid `auto-fit`,列数自动适配容器宽度。Hover 图片放大。 #### 网格相册 `[album-grid]` ``` [album-grid set="2,sm-2,md-3,lg-4"] [img src="1.jpg"]图1[/img] [img src="2.jpg"]图2[/img] [/album-grid] ``` | 属性 | 默认值 | 说明 | |------|--------|------| | `set` | - | 列数:N, sm-N, md-N, lg-N | Hover 图片放大,支持 `[grid-span]` 跨行跨列。 #### 网格跨度 `[grid-span]` ``` [grid-span set="row-2,col-2"] [img src="hero.jpg"]主图[/img] [/grid-span] ``` | 属性 | 默认值 | 说明 | |------|--------|------| | `set` | - | row-N 跨行,col-N 跨列 | #### 瀑布流相册 `[album-masonry]` ``` [album-masonry cols="3"] [img src="1.jpg"]图1[/img] ... [/album-masonry] ``` | 属性 | 默认值 | 说明 | |------|--------|------| | `cols` | 3 | 列数 2–5,响应式自动降级 | CSS `column-count` 实现,图片按高度错落排列。Hover 图片放大。 #### 横向滚动相册 `[album-hscroll]` ``` [album-hscroll cols="4" speed="60"] [img src="1.jpg"]图1[/img]... [/album-hscroll] ``` | 属性 | 默认值 | 说明 | |------|--------|------| | `cols` | 4 | 每行图片数 | | `speed` | 60 | 像素/秒 | 奇数行左→右,偶数行右→左,自动循环。hover 暂停。JS 像素级动画,无缝衔接。 --- ### 引用 #### 站内文章 `[post]` ``` [post cid="60"][/post] ``` 自动提取标题、摘要、缩略图(自定义字段 `thumb` → 附件 → 正文 → 随机图)。 #### 站外文章 `[fpost]` ``` [fpost href="https://x.com" src="https://x.com/thumb.jpg" description="摘要"] 标题 [/fpost] ``` --- ### 其他 #### 原样输出 `[raw]` ``` [raw language="php"] ` 包装,主题可自定义样式 ## 扩展开发 ```php // 在主题 functions.php 或插件中注册 Typecho_Plugin::factory('Widget_Archive')->handleInit = function () { EasyShortCode_Parser::register('mytag', function ($atts, $content, $tag) { $name = htmlspecialchars($atts['name'] ?? 'default', ENT_QUOTES, 'UTF-8'); return '
' . $content . '
'; }); }; ``` `register(name, callback, override)` — 支持别名数组,override 控制是否覆盖已有。 ## 样式自定义 所有 CSS 类以 `esc-` 前缀,主题可覆盖。完整暗色模式支持(`.dark` 后代选择器)。 ### CSS 类名速查 | 短代码 | 主要类 | |--------|--------| | button | `.esc-btn` `.esc-btn-{type}` | | alert/tip | `.esc-alert` `.esc-tip` `.esc-alert-{type}` | | hide | `.esc-hide` `.esc-hide-spoiler` `.esc-hide-blur` | | progress | `.esc-progress` `.esc-progress-{color}` `.esc-progress-striped` `.esc-progress-animate` | | tabs | `.esc-tabs` `.esc-tab-label` `.esc-tab-content` | | timeline | `.esc-timeline` `.esc-timeline-marker` `.esc-timeline-date` `.esc-timeline-content` | | img | `.imgdiv` `.imgtitle` | | album-auto/grid/masonry/hscroll | `.album-auto` `.album-grid` `.album-masonry` `.album-hscroll` | | chat | `.chat-container` `.message` `.sent`/`.received` `.message-content` `.timestamp` `.avatar` | | file | `.file` `.fileimg` `.filetext` `.filedown` | | post/fpost | `.post_inner` `.post_img_inner` `.post_info_inner` | | grid-span | `.grid-span` `.grid-span-row-{n}` `.grid-span-col-{n}` | ## 安全说明 - `target="_blank"` 均含 `rel="noopener noreferrer"` - body 内容为作者受信 HTML,不转义 - 属性值全部 `htmlspecialchars()` 转义 - 枚举值白名单校验 ## 文件结构 ``` EasyShortCode/ ├── Plugin.php # 插件入口,钩子注册 ├── Parser.php # 解析引擎 + 20 个短代码实现 ├── README.md └── assets/ ├── style.css # 前端短代码样式(暗色模式) ├── frontend.js # 横向滚动相册动画 ├── editor.css # 后台工具栏 + 弹窗样式 └── editor.js # 后台工具栏 + 弹窗逻辑 ``` ## 许可 按 Typecho 惯例使用与修改。