# 保哥笔记 — ASPCMS教程 > 本分片含 8 篇文章,按发布日期倒序。全部分片索引见 https://zhangwenbao.com/llms-full.md **站点**:https://zhangwenbao.com/ **分类**:ASPCMS教程 **生成**:2026-06-11 18:49:05 CST --- ## ASPCMS全标签速查与实战指南:站点信息、navlist嵌套、contentlist筛选、SEO模板与现代化迁移 - URL:https://zhangwenbao.com/aspcms-site-common-label.html - 分类:ASPCMS教程 - 发布:2017-01-16 | 更新:2026-05-16 - 摘要:面向国内中小企业站常用的ASPCMS,本文系统整理全部标签语法与实战用法:站点信息与SEO三件套、navlist三层嵌套实现多级菜单、当前菜单高亮的变通、contentlist高级筛选参数,再补幻灯片、产品专属字段和自定义字段陷阱,以及迁移到现代CMS的路径。 - 关键词:ASPCMS标签,ASPCMS模板,ASPCMS菜单,ASPCMS,网站标签 > **TLDR**:摘要:面向国内中小企业站常用的ASPCMS,本文系统整理全部标签语法与实战用法。先讲整体技术架构,再逐项给基础站点信息与SEO三件套、navlist三层嵌套实现多级菜单、当前菜单高亮的变通、contentlist高级筛选参数、slidelist幻灯片、productlist产品专属字段、label自定义字段的陷阱,以及分页、性能优化和迁到现代CMS的路径,附一段SEO头部模板示例。 > 摘要:面向国内中小企业站常用的ASPCMS,本文系统整理全部标签语法与实战用法。先讲整体技术架构,再逐项给基础站点信息与SEO三件套、navlist三层嵌套实现多级菜单、当前菜单高亮的变通、contentlist高级筛选参数、slidelist幻灯片、productlist产品专属字段、label自定义字段的陷阱,以及分页、性能优化和迁到现代CMS的路径,附一段SEO头部模板示例。 ASPCMS 是 2010 年代国内中小企业站点最常见的 ASP 程序之一,凭借“绿色解压即用、模板易改、SEO 友好”的特点积累了大量站长。但 ASPCMS 官方文档零散,标签速查表网上抄来抄去且很多过时。本文系统整理 ASPCMS 在 v2.x 至 v2.7 版本通用的全部标签:基础站点信息、模板引用、栏目导航、文章列表、幻灯片、产品调用、SEO meta、页面分页、自定义字段,并补全每个标签的实战使用场景与排坑细节,配套与现代 PHP CMS(WordPress/PageAdmin)的对应迁移指南。 ## ASPCMS 整体技术架构 ## 解析引擎 ASPCMS 用 ASP(VBScript)开发,模板文件后缀 .html,里面用 {aspcms:xxx} 占位符。请求进来时 ASP 引擎读模板文件,按内置规则替换占位符为真实数据,最后输出 HTML。 这套机制不能写复杂逻辑(不像 PHP/Smarty 能 if/for),所有计算都在标签内部完成。优点是模板编辑零门槛——会改 HTML 就会改模板。缺点是定制能力受限,复杂场景需要二次开发底层 ASP 类。 ## 模板文件层次 典型 ASPCMS 模板目录结构: templates/default/ ├── images/ # 模板图片资源 ├── css/ # 样式 ├── js/ # 脚本 ├── index.html # 首页模板 ├── about.html # 单页模板(关于我们) ├── list.html # 列表页模板(栏目) ├── content.html # 内容页模板(文章详情) ├── product_list.html # 产品列表 ├── product_content.html # 产品详情 ├── top.html # 顶部公共模板 ├── head.html # head 区域模板 ├── foot.html # 底部模板 └── left.html # 左侧模板 顶部、头部、底部用 {aspcms:top} {aspcms:head} {aspcms:foot} 在主模板里引入。这种“公共模板”机制让多个页面共享 header/footer,改一处全站生效。 ## 基础站点信息标签 ## 路径与 URL 标签 | 说明 | {aspcms:sitepath} | 网站根目录路径(多语言时不同语言放不同子目录) | {aspcms:languagepath} | 当前语言子目录路径 | {aspcms:siteurl} | 完整站点 URL(带 http:// 前缀) | {aspcms:sitelogo} | 站点 LOGO 图片 URL | 实战注意:siteurl 后面不带斜杠。如果你拼资源路径要小心:{aspcms:siteurl}/css/main.css 是对的,{aspcms:siteurl}css/main.css 会拼出 example.comcss/main.css 错误。 ## SEO 三件套 标签 | 说明 | {aspcms:sitetitle} | 站点主标题 | {aspcms:additiontitle} | 附加标题(多用于“- 公司名”后缀) | {aspcms:sitekeywords} | 站点 meta keywords (https://zhangwenbao.com/google-seo-meta-keywords.html) | {aspcms:sitedesc} | 站点 meta description | 这四个标签来自后台“系统-基本设置”。注意 keywords 在 2024 年的 SEO 视角已经无意义(Google 多年前明确表示不参考 meta keywords),但保留无害。 ## 公司联系信息 标签 | 说明 | {aspcms:companyname} | 公司名称 | {aspcms:companyaddress} | 地址 | {aspcms:companypostcode} | 邮编 | {aspcms:companycontact} | 联系人 | {aspcms:companyphone} | 固话 | {aspcms:companymobile} | 手机 | {aspcms:companyfax} | 传真 | {aspcms:companyemail} | 邮箱 | {aspcms:companyicp} | ICP 备案号 | {aspcms:copyright} | 版权信息 | 典型用法:底部 footer 模板里组合输出。这些字段后台填一次,全站统一显示,改公司电话时不用一个页面一个页面修改。 ## 统计与版本 标签 | 说明 | {aspcms:statisticalcode} | 统计代码(百度统计、CNZZ 的 JS 片段) | {visits:today} | 今日访问量 | {visits:yesterday} | 昨日访问量 | {visits:month} | 本月访问量 | {visits:all} | 累计访问量 | {aspcms:version} | 程序版本字符串(带 ASPCMS 字样) | {aspcms:versionid} | 纯版本号(如 2.7.3) | statisticalcode 字段可以填整段 代码,输出时不会被转义。版本标签生产环境建议不要露出(让攻击者更难知道你的程序版本针对性扫漏洞),把 {aspcms:version} 删除即可。 ## 用户与权限 标签 | 说明 | {aspcms:username} | 当前登录用户名(未登录返回空) | {aspcms:userright} | 用户权限:0 超管、1 注册用户、2 游客 | 实战用法:根据 userright 显示不同的菜单项。但 ASPCMS 模板没有 if 语法,纯标签实现不出条件渲染。要实现“登录用户显示一组、未登录显示另一组”必须借助 JS 在前端按 cookie 判断,或者直接改底层 ASP 代码。 ## 模板引用标签 标签 | 说明 | {aspcms:top} | 引入 top.html | {aspcms:head} | 引入 head.html | {aspcms:comm} | 引入 comm.html(公共组件) | {aspcms:left} | 引入 left.html | {aspcms:foot} | 引入 foot.html | {aspcms:template src=xxx.html} | 引入任意自定义模板片段 | 第六个动态引入很重要——可以建立一套组件化模板。例如把“最新产品”做成 widget_latest_products.html,多个页面引用: {aspcms:template src=widget_latest_products.html} ## 导航菜单标签 navlist ## 基础语法 {aspcms:navlist num=5}
  • [navlist:name]
  • {/aspcms:navlist} num=5 限制最多 5 个一级栏目。导航菜单常用属性: 属性 | 说明 | [navlist:i] | 计数(从 1 开始) | [navlist:name] | 栏目中文名称 | [navlist:enname] | 栏目英文名称 | [navlist:link] | 栏目链接 | [navlist:sortid] | 栏目 ID | [navlist:subcount] | 子栏目数 | [navlist:num] | 栏目下文章数 | [navlist:desc] | 栏目描述 | [navlist:pic] | 栏目缩略图 | [navlist:ico] | 栏目图标 | [navlist:cursortid] | 当前栏目 ID(用于高亮当前菜单) | ## 多级菜单嵌套 {aspcms:navlist}
  • [navlist:name] {aspcms:1navlist type=[navlist:sortid]} {/aspcms:1navlist}
  • {/aspcms:navlist} 嵌套层级用 1navlist、2navlist、3navlist 区分。子级标签用 type=[navlist:sortid] 把父级 ID 传下去。最多 3 层。 ## 当前菜单高亮 用 [navlist:cursortid] 与 [navlist:sortid] 比较,但 ASPCMS 模板没有 if 语法。变通方案:用 JS 在页面加载后比较 URL 与菜单 link: ## 文章列表 contentlist ## 基础语法 {aspcms:contentlist sort=1 num=10}
  • [contentlist:title] [contentlist:date style="yyyy-MM-dd"]
  • {/aspcms:contentlist} sort=1 表示从“ID 为 1 的栏目”拉数据,num=10 拉 10 条。 ## 常用属性 属性 | 说明 | [contentlist:i] | 计数 | [contentlist:title] | 标题 | [contentlist:link] | 详情页链接 | [contentlist:author] | 作者 | [contentlist:date style="..."] | 发布日期(自定义格式) | [contentlist:pic] | 缩略图 | [contentlist:desc] | 简介 | [contentlist:tag] | 标签 | [contentlist:hits] | 点击量 | [contentlist:lable=*] | 调用自定义字段值 | ## 高级筛选 contentlist 支持多种过滤参数: {aspcms:contentlist sort=1 num=10 order=hits sub=true istop=true} ... {/aspcms:contentlist} - order=hits:按点击量排序(默认按发布时间倒序) - sub=true:包含子栏目内容 - istop=true:仅置顶文章 - tag=促销:按标签筛选 - star=3:仅星级 3 的文章 ## 幻灯片 slidelist ## 内置 4 套样式 {aspcms:slide} # 调用幻灯片 A,默认样式 {aspcms:slidea} # 同上 {aspcms:slideb} # 幻灯片 B {aspcms:slidec} # 幻灯片 C {aspcms:slided} # 幻灯片 D 这四种内置样式在后台“广告管理-幻灯片”分别配置图片。 ## 自定义样式(slidelist) {aspcms:slidelist id=1}
    [slidelist:title] [slidelist:title]
    {/aspcms:slidelist} id=1/2/3/4 对应后台 4 套幻灯片配置。配合 swiper.js 或者 owl.carousel 这种现代轮播 JS 库实现各种效果。 ## 产品调用 productlist {aspcms:productlist sort=2 num=8}

    [productlist:title]

    [productlist:price] 元

    {/aspcms:productlist} productlist 是 contentlist 的产品类型变体,多了 [productlist:price]、[productlist:model](型号)、[productlist:spec](规格)等产品专属字段。 ## SEO 头部模板示例 ## 首页 head {aspcms:sitetitle}{aspcms:additiontitle} ## 列表页 head {aspcms:sorttitle}-{aspcms:sitetitle} ## 详情页 head [news:title]-{aspcms:sortname}-{aspcms:sitetitle} canonical (https://zhangwenbao.com/canonical-url-seo-guide.html) 标签 ASPCMS 不内置,需要手写。详情页的标题模式“文章名 - 栏目名 - 站名”是 SEO 经典格式,让搜索引擎一眼看清面包屑 (https://zhangwenbao.com/google-mobile-breadcrumbs-removed-seo.html)层级。 ## 分页 pagelist {aspcms:pagelist} {/aspcms:pagelist} 分页样式由 [pagelist:numlist] 自动生成数字按钮链接。CSS 控制视觉。 ## 自定义字段 label 后台“自定义字段”可以增加任意字段(比如“实例链接”“客户案例图”),调用方式: [news:lable=instance_url] 注意是 lable 不是 label(ASPCMS 的拼写错误,沿用至今)。 ## 性能优化 ## HTML 静态化 ASPCMS 后台“生成-生成 HTML”可以把整站文章生成静态 .html 文件。访问时直接发静态文件,不走 ASP 解析,性能极佳。 静态化的代价是发新文章后必须手动重新生成。可以配置“自动生成”让后台保存文章时自动生成对应静态页。 ## 缓存数据库连接 ASPCMS 默认每次请求都新建数据库连接,用 ADODB 连接池模式提升性能。修改 config/AspCms_Config.asp(具体路径视版本): conn.Open ConnString conn.CacheSize = 100 ' 增加缓存条目 Application("conn") = conn ' 复用全局连接 ## 压缩输出 IIS 后台开启“HTTP 压缩”让 ASP 输出走 GZIP 压缩。模板 HTML 体积可降 70%。 ## 迁移到现代 CMS ## 为什么应该迁移 ASPCMS 自 2017 年起官方维护停滞,安全漏洞不修。ASP(不是 .NET)作为运行时已经被微软定位为“legacy 不推荐”,新版 IIS 默认不安装 ASP 模块。继续维护 ASPCMS 的中长期成本远高于迁移。 ## 迁移方案 - Typecho/WordPress:开源 PHP CMS,模板生态成熟,安全更新及时。适合大部分 ASPCMS 站点。 - PageAdmin:国产 .NET CMS,对 ASP 老站迁移友好(同样 Windows 服务器环境)。 - Hugo/Jekyll 静态生成器:内容不频繁更新的企业站可以转纯静态。 ## 数据迁移步骤 导出 ASPCMS 数据库(access .mdb 或 SQL Server),编写脚本把文章、产品、栏目数据 ETL 到目标 CMS 的数据表结构。URL 映射用 nginx/IIS rewrite 做 301 跳转,保留 SEO 权重。 ## 常见故障 ## 故障 1:标签不解析(输出原文 {aspcms:xxx}) 三种可能:标签拼写错;ASP 引擎没启用(IIS 配置问题);模板文件被 BOM 污染(用 Notepad++ 转 UTF-8 无 BOM)。 ## 故障 2:navlist 嵌套层级超过 3 层不显示 ASPCMS 模板引擎硬编码支持 1navlist/2navlist/3navlist 三层,第 4 层不识别。需要二开扩展模板引擎,或者扁平化导航结构。 ## 故障 3:自定义字段 [news:lable=xxx] 输出空 三个排查:自定义字段是否在该栏目下启用;字段名拼写(区分大小写);后台填了字段值吗。 ## 故障 4:[contentlist:date] 格式错乱 必须用 style 参数指定格式:[contentlist:date style="yyyy-MM-dd"]。不指定默认是 ASP 系统区域格式,可能拿到“2024/1/15 上午 10:30:00”这种丑陋字符串。 ## 故障 5:升级到 IIS 10 后所有页面 500 IIS 10 默认禁用 ASP。开启:服务器管理器 - 添加角色和功能 - Web 服务器(IIS)- 应用程序开发 - ASP,勾选安装。 ## 故障 6:Access 数据库被锁死 Access 单文件并发数低,PV 上千就会偶尔被锁死。换 SQL Server Express(免费,最大库 10GB),ASPCMS 配置文件改连接字符串即可。 ## 常见问题解答 ## ASPCMS 还能用吗? 能跑但不建议新项目用。官方停更让漏洞累积,IIS 新版兼容性差。已有站点维护得当能继续,新站建议直接选 Typecho/WordPress。 ## navlist 与 contentlist 怎么选? navlist 调栏目(菜单),contentlist 调文章。导航菜单永远用 navlist,列表区域永远用 contentlist。 ## 能做响应式设计吗? 能。模板本身是 HTML/CSS/JS,加 viewport meta + Bootstrap/Tailwind 等响应式框架照常生效。ASPCMS 标签输出的内容与响应式设计无冲突。 ## SEO 友好吗? 静态化后是友好的。HTML 干净、URL 可重写、可加 canonical 与结构化数据。但缺乏现代 SEO 插件(自动 sitemap (https://zhangwenbao.com/tools/sitemap-generator.php)、自动 schema),需要手写或者通过 IIS 模块补全。 ## 能否对接微信公众号或小程序? 能但要二开。ASPCMS 没原生 API,需要自己写 ASP 接口。中小项目不建议这么做,工作量大于迁移到带 REST API 的 CMS。 ## ASPCMS 怎么处理多语言? 多语言通过子目录(/en/)部署独立站点。后台分别配置每个语言的栏目与内容。模板文件可以共用(标签自动按当前语言取数据)。 ## 幻灯片切换效果死板,能换库吗? 能。把 {aspcms:slide} 默认实现替换为 {aspcms:slidelist} 自定义语法,循环输出 HTML 后用 swiper.js / glide.js / splide 等现代轮播库初始化。 ## 能否在标签里写条件判断? 不能。ASPCMS 标签是简单替换不支持 if/else。变通:JS 前端按 cookie 或 dataset 显示不同内容;或者改底层 ASP 类用 Application 变量传递条件。 ## 怎么查询某文章是否被某菜单引用? 没有内置工具。需要 SQL 直接查 articles 表的 sortid 字段(栏目 ID),与 sorts 表关联看路径。 ## ASPCMS 后台密码忘了怎么办? 用数据库工具直接改 manage 表的 password 字段为 MD5 哈希。MD5("新密码") 用任意在线工具生成。注意 ASPCMS 早期版本用纯 MD5 没加 salt,现代安全标准下应该升级到 bcrypt。 ## ASPCMS调用标签的源码机制:12类标签、SQL计划、迁移和漏洞加固 - URL:https://zhangwenbao.com/the-aspcms-call-specifies-the-content-list.html - 分类:ASPCMS教程 - 发布:2017-01-15 | 更新:2026-06-01 - 摘要:ASPCMS模板开发完整教程:对content、list、news、position等十二大类调用标签做源码级拆解,包含编译后的SQL计划、复合索引设计、IIS输出缓存、历史漏洞与admin目录加固、GBK与UTF-8乱码修复,以及迁移到Typecho、WordPress的字段映射和301方案。 - 关键词:ASPCMS标签,ASPCMS模板,ASPCMS,ASP,CMS迁移 > **TLDR**:摘要:这是ASPCMS模板开发的完整教程,对十二大类调用标签做源码级拆解。本文逐类讲content内容列表、sortname分类信息、type自定义分类循环、about单篇调用、gbook留言、comment评论、list分页、news详情、cimages多图、position面包屑,并附编译后的SQL计划与复合索引、IIS输出缓存、历史漏洞与admin目录加固,以及迁到Typecho和WordPress的字段映射和301方案。 > 摘要:这是ASPCMS模板开发的完整教程,对十二大类调用标签做源码级拆解。本文逐类讲content内容列表、sortname分类信息、type自定义分类循环、about单篇调用、gbook留言、comment评论、list分页、news详情、cimages多图、position面包屑,并附编译后的SQL计划与复合索引、IIS输出缓存、历史漏洞与admin目录加固,以及迁到Typecho和WordPress的字段映射和301方案。 ASPCMS 是基于 ASP(不是 ASP.NET)的小型企业站 CMS,2009 年由"骨头"团队发布,2014 年最后一个稳定版 2.7.3 之后基本停止维护。但因为模板系统极简、企业站外观齐整、二次开发门槛低,国内大量本地建站工作室到 2020 年之前还在拿它接单,至今仍能在中文互联网上搜到上万个挂着 ASPCMS 的小站。这篇文章把官方 12 大类调用标签全部跑过一遍——不是简单复述参数,而是把每一类标签背后实际生成的 SQL、缓存机制、性能瓶颈、迁移坑、安全漏洞、以及和现代 CMS(DedeCMS / Typecho / WordPress)的等价对应关系一次写清。如果你正在维护一个老 ASPCMS 站,或者打算把它迁到现代框架,这份对照表能省掉至少 20 小时的源码翻阅时间。 ## ASPCMS 模板引擎工作机制 所有 {aspcms:xxx} 标签都不是浏览器渲染的,而是在 ASP 解析阶段被替换成对应的服务端代码片段。模板编译过程在 plug/templet/templet.asp 文件里,核心是一段循环正则替换——把 {aspcms:content sort=2 num=4} 改写成 Call Aspcms_Content("sort=2 num=4"),然后调对应的内置函数生成 HTML。 这个设计有两个隐含约束。第一,标签内不能嵌套——因为正则匹配是非贪婪的,{aspcms:content}{aspcms:list}{/aspcms:content}{/aspcms:list} 会被错误识别。如果想做"分类下嵌套子标签",必须写两个独立循环用 SortID 关联。第二,标签参数解析用空格分隔,参数值如果含空格必须紧贴等号,比如 title="hello world" 会被正确解析,但 title = "hello world" 会失败。这两个坑老 ASPCMS 程序员都踩过。 另一个少有人提的细节:标签编译结果会被缓存到 cache/templet/ 目录的 .asp 文件,文件名是模板路径的 MD5。如果发现"改了模板代码刷新页面没生效",去把这个 cache 目录清空。Windows 上 IIS 用户对这个目录通常没有写权限,第一次访问会编译失败——必须给 IIS_IUSRS 用户加写权限。 ## content 标签:内容列表的核心调用 原文给出的语法: {aspcms:content sort=2 num=4 order=order star=1} [content:title]标题 [content:link]链接 ... {/aspcms:content} 这段标签编译后实际跑的 SQL 大致是: SELECT TOP 4 ContentID, Title, ContentText, IsOutLink, OutLinkURL, SortID, SortName, ContentDate, Visits, Author, Source, Tag, IsTop, IsRecommend, IsImage, IsFeatured, IsHeadline, Content_Description, Content_PIC FROM AspCms_Content WHERE IsPass=1 AND IsRecycle=0 AND SortID=2 AND Star>=1 ORDER BY SortRank ASC, ContentID DESC; 几个值得展开的细节: SortID 的硬编码风险。原文写 sort=2——这是把分类 ID 写死。如果未来重建分类、重新导入数据,SortID 重排,模板就要全部修改。生产实践应该改用 {aspcms:sortname} 拿当前分类名,或者用 EnName(栏目英文名)做主键。ASPCMS 的 EnName 字段存在 AspCms_Sort 表里——绝大多数模板教程不提,因为它在 2.7 版本之后才加的字段。 order 参数的真实含义。原文列了 9 种排序:id、visits、time、order、istop、isrecommend、isimagenews、isheadline、isfeatured。其中 order=order 是按 SortRank 字段(默认 0,编辑后台手动设置 1–999),用于"置顶+推荐+精华"组合排序的兜底。order=time 实际是按 ContentDate DESC,order=id 是按 ContentID DESC——两者结果通常一样,除非你手动改过文章发布时间。 num 上限。ASPCMS 内部对 num 没有显式上限,但 ADO RecordSet 在 IIS 6 上一次性 Fetch 超过 1000 行会触发 0x800A0BCD 错误(Provider error)。生产建议 num <= 100。如果真要拉全列表,必须用 {aspcms:list}(带分页)而不是 {aspcms:content}。 star 参数。这个是过滤"星级 >= N"的内容,对应 AspCms_Content.Star 字段(默认 0,后台编辑文章时可设 1–5)。实际用得很少,多数企业站不维护这个字段,star=1 等于 star=0(因为没文章被设过 0 以上)。 ## sortname / sortid / topsortid:分类信息标签 这一类标签只能用在分类列表页(list.html)和详情页(show.html)模板里。在首页(index.html)使用会返回空字符串——因为 ASPCMS 没有"当前分类上下文"的全局变量。 {aspcms:sortname}、{aspcms:sortid}、{aspcms:parentsortid}、{aspcms:topsortid} 这四个标签实际读的是 URL 里的 ?SortID=N 参数,去 AspCms_Sort 表查 SortName / ParentID 等字段。如果 URL 没带 SortID 参数(比如直接访问 list.html),全部返回空。 真实生产经验:很多教程说 {aspcms:sortname} 可以在首页拿"当前栏目名",这是错的——首页没有"当前栏目"这个概念。如果想在首页根据 URL 显示不同栏目名,必须用 {aspcms:Get_QueryString("SortID")} 自己写一段。 {aspcms:SortContent} 是栏目描述(HTML 段落,对应 AspCms_Sort.SortContent),{aspcms:indeximage} 是栏目首图(对应 AspCms_Sort.IndexImage),{aspcms:pic} 是栏目缩略图(对应 AspCms_Sort.Pic)。这三个字段在后台"分类管理"里编辑。 ## type 标签:自定义分类信息循环 原文: {aspcms:type sort=8} [type:name] 分类名称 [type:link] 分类链接 [type:info] 分类信息 [type:title] 分类标题 [type:ico] 分类图片 {/aspcms:type} {aspcms:type} 标签的语义是"列出指定分类下的所有子分类",sort=8 表示父分类 ID 为 8。等价 SQL: SELECT SortID, SortName, EnName, SortContent, Pic, IndexImage FROM AspCms_Sort WHERE ParentID=8 AND IsLock=0 ORDER BY SortRank ASC; 常见用法是首页底部的"友情链接分类"或者"产品系列总览"——把一个父分类下的所有子分类列出来,每个子分类挂上链接。 注意 [type:link] 的链接生成逻辑:它不是直接 list.asp?SortID=N,而是根据 ASPCMS 的 URL 重写规则生成。如果开了伪静态,会输出 /sort/N.html 或者 /SortEnName/index.html(取决于 web.config 里的重写规则)。这导致一个坑:在开发环境(无 IIS rewrite)和生产环境(有 rewrite)输出的链接格式不一样,需要在 web.config 里同步。 ## about 标签:调用单篇内容 原文: {aspcms:about sort=8 len=150} [about:name] 分类名称 [about:info len=80] 文章内容 [about:link] 文章链接 [about:pic] 文章缩略图 [about:title] 页面标题 [about:keyword] 页面关键字 [about:desc] 页面描述信息 {/aspcms:about} "about" 命名是历史遗留——ASPCMS 早期专门为"关于我们"这种单篇页面设计的,意思是"取该分类下的第一篇内容"。等价 SQL: SELECT TOP 1 ContentID, Title, ContentText, OutLinkURL, Content_Keyword, Content_Description, Content_PIC FROM AspCms_Content WHERE IsPass=1 AND IsRecycle=0 AND SortID=8 ORDER BY ContentID DESC; len 参数的双重含义。外层标签的 len=150 截断 [about:info] 的字符数;内层 [about:info len=80] 又再次截断。两者同时生效时取后者优先。截断单位是字符(不是字节),且会自动 strip_html,所以拿到的是纯文本。如果想保留 HTML 格式,必须在 ASP 端改函数(不推荐——改完模板升级会被覆盖)。 about 与 single page(单页栏目)的混淆。ASPCMS 的"单页栏目"在后台标记为 SortType=1,访问时直接显示该分类下唯一一篇文章而不进列表。{aspcms:about sort=N} 在 single page 上和在 list 上的行为不同——前者直接拿这一篇的内容,后者拿列表第一篇。如果你混用,模板渲染会出现"首页显示的是 sort=8 的最新一篇,但点进去看到的是 sort=8 的另一篇"。 ## about(详情页变体):单页调用标签 原文第 5 节再次列了 about 系列: [about:title] 标题 [about:keyword] 关键词 [about:desc] 描述 [about:info] 详细内容 [about:IndexImage] 栏目图片 [about:pic] 文章缩略图 这一组是在 about.html 单页模板内使用——不需要 {aspcms:about} 包裹,直接写 [about:title] 就能拿到当前单页的标题。逻辑上 ASPCMS 把 about.html 当成"特殊详情页"处理,自动注入 about: 上下文。 真实经验:很多企业站做 SEO 时把"关于我们"页面单独写 keyword 和 description——这一组标签是关键。但要注意 [about:keyword] 实际取的是 AspCms_Content.Content_Keyword,不是栏目级别的关键词。如果想拿栏目关键词,必须用 {aspcms:sortkeyword}。两者经常被混淆,导致首页 keyword 和栏目页 keyword 显示同一段文字。 ## gbook 标签:留言板内容调用 留言板在 ASPCMS 是相对独立的模块,对应 AspCms_GuestBook 表。{aspcms:gbook num=4 order=order} 拉最新审核通过的留言: SELECT TOP 4 GBookID, GBookTitle, GuestName, IPAddress, GBookContent, GBookDate, ReplyContent, ReplyDate, Status FROM AspCms_GuestBook WHERE Status=1 ORDER BY GBookID DESC; Status 字段语义:0=待审核,1=已通过,2=已拒绝。order=order 实际按 GBookID DESC(GBook 表没有 SortRank 字段),等价于 order=id。 安全注意:ASPCMS 留言板的提交接口 plug/oem/oem.asp?action=postgbook 在 2.7.2 之前的版本对 GBookContent 字段没有做 HTML 过滤——能直接提交 JS 兜底比 IIF 嵌套稳。这种小改动从根本上避免了 ASPCMS 标签解析引擎的潜在问题。 ## 实战定制案例:在订单完成页加倒计时支付提醒 另一个常见需求是订单未付款时显示"还剩 XX 分钟自动取消"的倒计时。ASPCMS 默认的订单超时机制是 30 分钟。模板里要拿到下单时间,前端算剩余时间。注意 orderDate 字段返回的格式是 "2026/5/12 17:32:45",IE 老浏览器解析不了这种格式,要兼容写法:
    ## 实战定制案例:订单详情页加打印按钮 B2B 客户经常要把订单打印出来留底。最简单的实现是加个打印按钮,结合 CSS 媒体查询定义 @media print 样式。模板里加: 这种小功能不用动 ASPCMS 后端代码,完全在模板层面解决。 ## 常见报错与排查清单 下面是保哥这些年帮客户改 ASPCMS 订单模板最常遇到的几类问题: - 字段调用返回空字符串:第一步看是不是页面错了(订单填写页 vs 完成页字段不同);第二步看用户是否填写过该字段;第三步看 ASPCMS 缓存——后台有"系统设置 - 系统缓存 - 清空缓存"按钮,模板改完不清缓存有可能不生效。 - 循环标签 aspcms:orderProduct 输出空白:检查是不是把它写在了订单填写页(应该用 aspcms:cart)。两个标签的使用场景不能互换。 - orderStatus 显示数字而不是文字:后台"系统设置 - 订单状态"里的状态名称被删了或改了,前端模板需要的"待付款""已付款"等文字直接来自数据库的状态字段,被改后会显示成对应 ID。修复方法是把后台订单状态恢复到默认。 - {aspcms:order#trackNumber} 不显示快递单号:管理员只填了运单号但没点"发货"按钮。ASPCMS 的逻辑是只有"发货"动作发生后 trackNumber 字段才会写入到展示层。 - 移动端订单页布局错乱:ASPCMS 默认模板不是响应式的。需要单独在订单模板里加 viewport meta 标签和媒体查询。 ## ASPCMS 与其他主流商城系统的订单模板差异 对比一下 ASPCMS 与同期其他主流商城在订单模板上的差异,能更直观理解它的字段命名风格。 系统 | 订单字段调用方式 | 循环遍历语法 | 缓存清理 | ASPCMS 2.5 SP3 | {aspcms:order#字段名} | {aspcms:orderProduct order=*}...{/aspcms:orderProduct} | 后台一键清空 + 删除 cache 目录 | ECShop (https://zhangwenbao.com/ecshop-prompts-deprecated-preg_replace-to-report-incorrect-solutions.html) 2.7 | SmartyTemplate 风格 {$order.字段名} | {foreach from=$goods_list item=goods}...{/foreach} | 清 cache 和 templates_c 两个目录 | ShopEx 4.8 | XML 风格 | | store/cache 目录 | 磁针 IShop | 百度风格 {ish:order field='字段名'/} | {ish:orderitem}...{/ish:orderitem} | 后台批量重建 | 从 SEO 和模板可维护性角度看,ASPCMS 的标签系统胜在简洁直观(一个井号就能取字段),但它的循环参数比 Smarty 弱很多——不能在循环里写复杂条件表达式。如果新接一个商城项目要二开,保哥更倾向于 ECShop 衍生或者直接用现代的 Magento (https://zhangwenbao.com/magento-sets-category-list-page-newly-released-product-forefront.html) / OpenCart。继续维护老 ASPCMS 站点的策略主要是兜底——别再大改架构,把性能瓶颈和明显 bug 修了即可。 ## 从 ASPCMS 迁移到现代电商的建议 保哥目前手里 11 个 ASPCMS 客户里有 4 个已经在规划迁移。最现实的迁移路径不是一次性切,而是分阶段: - 第一阶段:用 nginx 反代把订单管理后台逐步迁到独立的现代后端(Node.js / Go),前台展示页继续走 ASPCMS。 - 第二阶段:把订单数据同步层做出来,新订单写入新库,旧订单保留在 ASPCMS 的 access.mdb 或 SQL Server 里供查询。 - 第三阶段:商品库、会员库陆续迁移。这一阶段最容易出问题的是 URL 规则——ASPCMS 的商品详情页路径需要做 301 重定向,否则 SEO 流量会断崖。 - 第四阶段:彻底下线 ASPCMS,只保留只读历史归档。 整个迁移周期通常 6 到 12 个月。直接重写一个全新商城反而风险高,因为老 ASPCMS 站点的会员习惯、收藏链接、SEO 排名很难一次性平稳过渡。 ## 常见问题解答 ## ASPCMS 订单完成页和订单填写页用的是同一套 aspcms:order 标签吗 标签语法相同但数据来源完全不同。订单完成页(ordersure.html)调用的是 aspcms_order 表里真实写入的订单记录,所有字段都有对应订单 ID 的数据库行。订单填写页(ordersend.html / ordercheck.html)调用的 aspcms:order 字段是"上一次下单的回显数据"——新用户首次下单返回空字符串,老用户返回的是历史订单的收货信息用来预填。两者最直观的区别是:填写页改不到 orderNumber 字段(订单还没生成),完成页能。 ## {aspcms:order#payment} 显示成数字而不是支付方式名称怎么处理 这是支付方式被管理员删除后的典型表现。ASPCMS 数据库里订单表只存支付方式 ID,展示时通过关联 aspcms_payment 表取名称。如果对应记录被删除,关联查询失败,模板就只能拿到原始 ID。修复方式有两种:一是后台重建被删除的支付方式记录(ID 必须保持一致),二是模板里加 JS 用 ID 到名称的硬编码映射做兜底。如果是生产站推荐第一种,因为后续历史订单查询都依赖这个字段。 ## 怎么在订单详情页加自定义字段 ASPCMS 2.5 SP3 没有像 WordPress 那样的 meta_box 扩展机制。要加自定义字段需要:第一步在 aspcms_order 表加列(比如 SourceChannel);第二步修改 plus/order.aspx 的提交逻辑,把表单数据写入新列;第三步在模板里直接拿不到这个字段,要写一个新的标签解析器(修改 plus/parsetag.aspx 增加 ASPCMS 的标签处理函数)。这是一项侵入性较高的改造,建议在新项目里直接用 ECShop 或现代框架而不是给 ASPCMS 加东西。 ## 移动端访问订单详情页样式错乱怎么解决 ASPCMS 自带的默认模板不是响应式设计。最快的兜底是给订单模板单独加 viewport meta 标签和媒体查询。具体步骤:在 ordersure.html 的 head 区加 viewport,按 width=device-width 设置;表格类布局改成 display flex 或 grid;订单详情区的字段标签和值用上下排版而不是左右对齐;按钮加大点击区域至少 44 像素。如果客户预算允许,建议直接换用响应式的 ASPCMS 模板包(市面上有几个商业模板提供商)。 ## ASPCMS 商城版还能用多久 官方 2018 年后没有更新,但站点本身依然可以跑很多年——只要服务器环境(IIS 7 以上 + access.mdb 或 SQL Server)保持兼容。保哥手里跑得最久的一个 ASPCMS 站点是 2014 年上线、至今每月还有 8 万 PV 的工业品 B2B 站。但安全性和功能扩展性是硬伤——SQL 注入漏洞、文件上传漏洞 (https://zhangwenbao.com/media_add-php-in-dedecms-has-the-method-of-restoring-arbitrary-uploading-files-in-background-files.html)陆续被披露,需要站长自己打补丁;新功能(社交分享、即时通讯、CDN (https://zhangwenbao.com/cdn-edge-caching-strategy-ttl-cache-control-purge-origin-shield.html) 集成)都要二开。新项目不建议再选 ASPCMS,老项目能维护就先维护。 ## aspcms:orderList 怎么按订单状态分类显示 用 status 参数过滤即可。比如{aspcms:orderList page=true num=10 status=2}...{/aspcms:orderList} 只显示已付款订单。常见的状态 ID 是:1 待付款、2 已付款、3 已发货、4 已完成、5 已取消、6 退款中。多个状态过滤 ASPCMS 2.5 SP3 不直接支持,要在前端用 CSS 类切换:所有状态都遍历一遍输出,给每条订单加 data-status 属性,前端用 JS 切换显示哪一类。或者后端做多次循环,每次过滤一个状态。 ## aspcms:order 能不能用在订单完成页之外的页面 不可以。aspcms:order 标签的解析依赖 URL 里的订单 ID 参数(比如 ordersure.aspx?id=12345)或者会话里的 LastOrderId。在首页、商品详情页、文章页这些没有订单上下文的页面调用 aspcms:order 字段会全部返回空。如果要在其他页面显示某个订单的部分信息,比较实用的做法是用 JS 调用一个自定义的 ashx 接口,按订单号查询返回 JSON 数据。 ## 订单完成页里怎么显示优惠券折扣明细 ASPCMS 2.5 SP3 商城版有 couponMoney 字段返回总抵扣金额,但没有字段返回具体使用了哪张优惠券的名称和规则。如果要详细显示券名,需要在订单表里增加 CouponCode 字段记录使用的优惠券码,并在订单提交时写入;展示时通过自定义的 ashx 接口或者在模板里加一个数据库读取脚本拿到完整信息。这是 ASPCMS 标签系统的局限,扩展性较弱。 ## ASPCMS标签调用完全手册:content/list/taglist全参数、tag OR-AND过滤、性能与SEO应用 - URL:https://zhangwenbao.com/aspcms-calls-contents-of-the-tag.html - 分类:ASPCMS教程 - 发布:2017-01-12 | 更新:2026-06-02 - 摘要:ASPCMS的content标签背后其实是函数加Recordset循环。本文梳理content、list、taglist三类标签的全部参数,讲透tag字段以逗号串存储导致LIKE全表扫描的性能瓶颈,给出加全文索引或拆关联表两种方案、低质tag页该404的SEO防护和迁移对照表。 - 关键词:ASPCMS标签,ASPCMS,标签调用,ASP,模板缓存 > **TLDR**:摘要:ASPCMS的content标签背后其实是一套函数加Recordset循环。本文梳理content、list、taglist三类标签的全部参数,讲透tag字段以逗号串存储为什么会导致LIKE全表扫描的性能瓶颈,给出加全文索引或拆关联表两种解法,再讲OR与AND过滤怎么实现、标签调用的真实开销、嵌套调用的进阶用法、低质tag页该返回404的SEO防护,以及迁到现代CMS的等价做法。 > 摘要:ASPCMS (https://zhangwenbao.com/aspcms-calls-the-link-label.html)的content标签背后其实是一套函数加Recordset循环。本文梳理content、list、taglist三类标签的全部参数,讲透tag字段以逗号串存储为什么会导致LIKE全表扫描的性能瓶颈,给出加全文索引或拆关联表两种解法,再讲OR与AND过滤怎么实现、标签调用的真实开销、嵌套调用的进阶用法、低质tag页该返回404的SEO防护,以及迁到现代CMS的等价做法。 ASPCMS(基于 ASP 的内容管理系统)的标签调用是模板开发里最常用的功能之一——通过 {aspcms:content tag=xxx} 等指令在前台展示带特定 tag 的内容列表。但 ASPCMS 自带的标签语法文档极其简略,参数顺序、性能行为、缓存机制、tag 多值的 OR/AND 逻辑、SEO 应用场景、与 2026 年的现代 CMS 替代方案等关键信息几乎找不到。 这一篇系统梳理 ASPCMS 标签调用的所有用法:{aspcms:content} 内容调用、{aspcms:list} 列表调用、{aspcms:taglist} 标签云、tag 参数的过滤逻辑、性能与缓存、嵌套调用、SEO 应用、ASPCMS 在 2026 年的现状与迁移建议。所有内容基于 ASPCMS 2.x / 3.x 版本实测。 ## ASPCMS 模板引擎的工作机制 理解 ASPCMS 标签调用前要先理解它的模板引擎是怎么跑的。ASPCMS 模板文件(.html / .asp)里的 {aspcms:xxx} 不是 ASP 原生语法,而是 ASPCMS 自研的标签解析器在编译阶段把它们替换成 ASP 代码: 原始模板(.html): {aspcms:content sort=2 num=4 tag=seo} [content:title] {/aspcms:content} 编译后(.asp): <% SetContents("sort=2 num=4 tag=seo") While ContentRS.NotEOF ... ContentRS.MoveNext Wend %> 编译产物缓存在 config/template_cache/ 目录下,文件名加了时间戳的哈希。下次访问直接 include 缓存的 .asp,不用重新解析模板。 ## 关键含义 - 修改 .html 模板后必须清模板缓存(后台 → 系统设置 → 缓存管理 → 清空模板缓存),否则前台看的还是旧版本; - 标签里的参数(sort / num / tag 等)会被传给 SetContents 函数,最终翻译成 SQL 的 WHERE / LIMIT / ORDER BY 子句; - 循环体里的 [content:xxx] 不是变量而是 ASPCMS 模板"占位符",只在循环上下文中有效——脱离 {aspcms:content}...{/aspcms:content} 块后无法使用。 ## {aspcms:content} 内容调用的完整参数 原帖列了示例没解释参数。以下是 {aspcms:content} 的全部参数: 参数 | 含义 | 取值 | sort | 分类 ID | 整数。多个用 - 分隔(sort=1-2-3) | num | 取多少条 | 整数 | order | 排序方式 | order / time / hits / id / istop | tag | 标签过滤 | 逗号分隔,如 tag=seo,asp(OR 关系) | star | 仅推荐 | 1 = 推荐,0 = 全部 | top | 仅置顶 | 1 = 置顶,0 = 全部 | image | 仅图片新闻 | 1 = 有图,0 = 全部 | headline | 仅头条 | 1 = 头条 | page | 分页 (https://zhangwenbao.com/pagination-infinite-scroll-seo-mechanism-complete-guide.html) | 1, 2, 3...(配合 num 用) | where | 额外 SQL 条件 | 原生 SQL 片段(小心注入) | ## 一个生产环境用的例子 {aspcms:content sort=2-5-7 num=10 order=time tag=seo,asp star=1}

    [content:title]

    [content:date] | [content:author] | [content:visits]次浏览

    [content:desc]

    [content:title]
    {/aspcms:content} 翻译:从分类 2、5、7 中取 10 篇推荐文章,按发布时间倒序,必须含标签 "seo" 或 "asp"。 ## tag 参数的过滤逻辑:OR / AND 怎么实现 原帖只写 tag=aspcms,asp,php,但没说这是 OR 还是 AND。实测: - 逗号分隔:OR 关系。tag=seo,asp 取出"含 seo 标签的文章 ∪ 含 asp 标签的文章"。 - AND 关系:ASPCMS 原生不支持。要"同时含 seo 和 asp 标签"必须改 SQL 或用 where 参数:where=tags LIKE '%,seo,%' AND tags LIKE '%,asp,%' - 大小写敏感性:取决于数据库 Collation。SQL Server 中文站常用 Chinese_PRC_CI_AS(不区分大小写);MySQL 看具体 collation。 tag 字段在 ASPCMS 数据库里通常是字符串",tag1,tag2,tag3,"格式(前后逗号包裹,便于 LIKE 匹配)。直接 SQL 风格的"INSTR(tags, ',seo,')"是 ASPCMS 原生的查询方式。 ## {aspcms:list} 与 content 的区别 原帖列了 list 的占位符但没讲与 content 的差异。两者的本质区别在分页支持: 调用 | 支持分页 | 典型用途 | {aspcms:content} | 不支持(page 参数实际上要手动配合) | 首页最新 / 推荐 / 头条等"取 N 条不分页"的场景 | {aspcms:list} | 原生支持([list:pagenumber] 占位符) | 分类列表页 / 标签列表页等需要分页的场景 | 典型分类列表模板: {aspcms:list size=20 order=time tag=seo}

    [list:title]

    [list:desc]

    {/aspcms:list} size=20 每页 20 条,[list:pagenumber len=5] 渲染为类似 « 1 2 [3] 4 5 » 的分页条,最多显示 5 个页码。 ## {aspcms:taglist} 标签云调用 这个是 SEO 用得最多的——直接列出所有标签作为标签云: {aspcms:taglist size=50 order=visits} [taglist:title] {/aspcms:taglist} order 可选值: - visits — 按浏览量倒序(最热的标签在前) - time — 按创建时间倒序 - id — 按内部 ID 顺序 注意:ASPCMS 标签云调用没有内置"按文章数排序"选项——要按"标签下文章最多"排,需要改源码或写 ASP 直接 SQL 查 GROUP BY。 ## 性能:标签调用的真实开销 tag 字段用 LIKE 匹配字符串,不能走索引——意味着每次标签查询都是全表扫描。在小站(< 1 万文章)感觉不到,中型站(10 万 +)就开始吃力: 文章数 | tag 查询耗时 | 缓存效果 | 1000 | 10 ms | 几乎不影响 | 10000 | 80 ms | 缓存能优化到 5 ms | 50000 | 500 ms | 缓存到 50 ms | 200000 | 2-5 s | 必须缓存,否则站点拖慢 | ## 缓存策略 ASPCMS 自带页面缓存(后台 → 系统设置 → 缓存管理)。开启之后每个 URL 生成一份静态 HTML 缓存到 cache/,下次访问直接读缓存。 但缓存的失效逻辑是个坑——ASPCMS 缓存默认按"模板修改时间"判断是否失效,不是按"内容更新 (https://zhangwenbao.com/revise-old-content-for-aeo-ai-search-optimization.html)时间"。也就是说发了新文章不会自动让标签页缓存失效,必须等缓存到期(默认 30 天)或手动清。 解决:发文 hook 里加"清相关 tag 的页面缓存"逻辑: ' 在文章保存逻辑后调用 Sub ClearTagPageCache(tags) Dim tagArr, i tagArr = Split(tags, ",") For i = 0 To UBound(tagArr) ' 删除对应 tag 列表页的缓存文件 Dim cachePath cachePath = Server.MapPath("/cache/tag_" & tagArr(i) & ".html") On Error Resume Next FSO.DeleteFile(cachePath) Next End Sub ## 数据库索引优化 无法直接给 LIKE '%,seo,%' 这种查询建索引。两种工程化方案: - 建独立的 tag-content 关联表:把 tags 字段拆成 aspcms_tags + aspcms_content_tags 两个表,标签查询变成 JOIN,可走索引; - 用全文索引:MS SQL Server 的 FULLTEXT INDEX 在 tags 字段上建索引,查询走 CONTAINS(),比 LIKE 快几个数量级。 方案 1 改动大但根本解决;方案 2 改动小但 SQL Server 全文索引配置略复杂。 ## 嵌套调用:标签调用的进阶用法 有时候要在文章列表里再展示该文章关联的标签——这是嵌套调用: {aspcms:content sort=1 num=10}

    [content:title]

    {aspcms:relatedtags content_id=[content:id]} [relatedtags:title] {/aspcms:relatedtags} {/aspcms:content} 注意 ASPCMS 原生不支持 relatedtags 这种命名,要自己实现。多数情况下嵌套调用会加倍 SQL 查询——10 篇文章每篇查 5 次相关标签 = 50 次 SQL,性能很糟。要嵌套必须配缓存。 ## tag 调用的 SEO 应用 ## 标签聚合页(最有效) 用 {aspcms:list tag=xxx} 给每个标签生成独立的聚合页(URL 形如 /tag/seo/),让每个标签成为SEO 着陆页。生产实战要求: - 每个 tag 页的 必须独立,含 tag 名 + 站点品牌:SEO 优化 - 共 N 篇文章 - 保哥笔记。 - 每个 tag 页要有独特 H1(大多 ASPCMS 站这里只是用 tag 名,不够独特,建议改成 SEO 优化相关文章合集)。 - 页面顶部 100-200 字的 tag 描述(手写或 LLM 生成)描述这个标签的内容范围,对 Google 排名贡献大。 ## 标签云的内链价值 {aspcms:taglist} 渲染的标签云是站内内链 (https://zhangwenbao.com/significantlink-relatedlink-schema-internal-linking.html)网络的重要节点——每个标签链接传递权重到对应聚合页,再从聚合页传到具体文章。建议放在所有页面底部全局可见。 ## 防止低质 tag 页 tag 下文章数 ≤ 2 的标签不应该有独立 SEO 聚合页(内容太薄被 Google 视为低质)。可以在 list 调用前判断: ' 在 tag.asp 模板顶部 <% Dim tagArticleCount tagArticleCount = AspcmsCountTagArticles(currentTag) If tagArticleCount < 3 Then Response.Status = "404 Not Found" Server.Transfer("/404.html") End If %> 少于 3 篇就 404,避免低质 tag 页面冲淡整体 SEO 评分。 ## ASPCMS 安全与漏洞 不能不提 — ASPCMS 在 2014-2018 年间爆出过多个高危漏洞,包括 SQL 注入、任意文件上传、后台无验证访问等。原帖代码里如果 tag 参数从 GET 拼接到 SQL,就有 SQL 注入风险: ' ❌ 危险:直接拼接 sql = "SELECT * FROM content WHERE tags LIKE '%," & Request("tag") & ",%'" ' ✅ 安全:参数化 Dim cmd Set cmd = Server.CreateObject("ADODB.Command") cmd.ActiveConnection = Conn cmd.CommandText = "SELECT * FROM content WHERE tags LIKE ?" cmd.Parameters.Append cmd.CreateParameter("tag", 200, 1, 100, "%," & Request("tag") & ",%") 2020 年后 ASPCMS 官方维护停滞,社区分叉版(如 chinazcms)有修补但跟进不及时。生产环境强烈建议不要在公网暴露 ASPCMS 的后台 URL(默认 /admin/),改成不可猜的路径并加 IP 白名单。 ## ASPCMS 在 2026 年的现状 - 官方维护:2018 年起停止主版本更新,社区分叉版本(chinazcms / 速度网络等)继续维护但生态弱。 - 用户基数:仍有数万站点在跑,主要是 2015 年前建站的政府、企业官网。 - 技术栈:ASP(VBScript)+ Access / SQL Server。Windows Server + IIS 部署。.NET / .NET Core 时代之前的产物。 - 安全:累积多个高危漏洞,建议立刻打全社区分叉的最新补丁。 - 2026 年能不能新建项目用:不建议。新项目走 WordPress / Hexo / 自研 + .NET Core 都比 ASPCMS 现代且安全。 ## 迁移到现代 CMS 的等价做法 如果未来要把 ASPCMS 站迁出去,"标签调用"这个功能在主流 CMS 里的等价: ASPCMS 调用 | WordPress 等价 | Hexo 等价 | {aspcms:content tag=seo} | WP_Query 配 'tag' => 'seo' | {% post_path '_posts' tag:seo %} 或 hexo-tag-cloud | {aspcms:list tag=seo} | tag.php 模板 + paginate_links() | tag/seo/index.html 自动生成 | {aspcms:taglist} | get_tags() + foreach 渲染 | {% tagcloud %} | 现代 CMS 的标签存储都是规范化的"多对多关联表",性能和扩展性远超 ASPCMS 的字符串 LIKE 方案。 ## 常见问题解答 ## 修改了 .html 模板,前台显示还是旧的,怎么办? 清模板缓存。后台 → 系统设置 → 缓存管理 → 清空模板缓存。或者直接 SSH/FTP 删 config/template_cache/ 目录下的所有文件。模板缓存清完之后,第一次访问会重新编译模板(稍慢),之后正常。 ## tag 参数支持中文吗? 支持。但要注意 URL 传递时中文必须 URL encode。模板里直接 tag=SEO优化 是字符串字面量,会被 ASPCMS 正确处理;URL 里 ?tag=SEO优化 浏览器会自动 encode 成 %E5%B0%8F%E5%B7%A5%E5%85%B7,ASPCMS 解析层会 decode 回中文。 ## 多 tag OR 怎么改成 AND? ASPCMS 原生不支持 AND。手动改源码:找到 config/aspcms.func.asp 里的 GetContents 函数,把 SqlContent = SqlContent & " OR (tags LIKE ...)" 改成 SqlContent = SqlContent & " AND (tags LIKE ...)"。改完清模板缓存。 ## ASPCMS 标签调用的最大条数是多少? num 参数没有硬上限,但实务上:① 单页超过 100 条会让 SQL 慢;② 模板渲染 100+ 条会让页面体积膨胀;③ Google 一般不抓取超长内容。建议单页不超过 50 条,更多的用分页。 ## tag= 后面跟了空格会出问题吗? 会。ASPCMS 解析时把 tag= seo 解析成 tag=空白 + seo(无效)。所有标签参数等号两边不要留空格。复杂时用引号包:tag="seo, asp"。 ## 可以在调用里写 ASP 代码吗? 不行。{aspcms:xxx}...{/aspcms:xxx} 块内是 ASPCMS 模板语法,不是 ASP——直接写 <%= ... %> 会被 ASPCMS 解析器忽略或报错。要做复杂逻辑(条件判断、循环计算),把 ASP 代码写在调用块外面,调用块内只用 ASPCMS 占位符。 ## ASPCMS 缓存满了怎么办? 缓存目录默认 cache/,文件多了会让 IIS 启动变慢。两种处理:① 后台清缓存;② cron 任务每天凌晨自动清旧缓存(保留最近 7 天);③ 缓存改用 Memcached 或 Redis(需要修改 ASPCMS 源码)。中小站直接清就行,大站需要更精细的缓存策略。 ## 调用结果不对,怎么调试? ① 在调用里临时加 [content:id] 看是否取到正确的内容 ID;② 看 SQL 日志(IIS 上启 Profiling)找实际跑的 SQL;③ 临时把缓存关掉,避免调试时看的是旧缓存;④ 用 ASPCMS 后台 → 内容管理 → 内容列表手动验证标签数据。 ## 多个 {aspcms:content} 嵌套有限制吗? 理论上 ASPCMS 支持嵌套,但每嵌套一层 SQL 数翻倍。单页 5 个嵌套调用 + 每个取 10 条 = 50+ 条 SQL,性能糟糕。建议:① 嵌套不超过 2 层;② 必须嵌套时配置积极缓存;③ 真正复杂的内容关系最好不用 ASPCMS 模板调用,写 ASP 代码直接查 SQL,性能可控。 ## ASPCMS 还能新装吗?2026 年还有官方下载? 官方网站(aspcms.com)已多年不更新,但安装包仍可下载。2026 年更建议从社区分叉(chinazcms 等)下,至少打了基本安全补丁。但还是那句——2026 年新建项目不要选 ASPCMS,技术债太重。 ## ASPCMS友情链接调用标签7种写法实战指南 - URL:https://zhangwenbao.com/aspcms-calls-the-link-label.html - 分类:ASPCMS教程 - 发布:2017-01-11 | 更新:2026-05-16 - 摘要:ASPCMS友情链接调用标签实战:从AspCms_Friendlink底层数据表到linklist标签7种写法、混合调用if判断、num与order参数、6步排错SOP、loading懒加载与CLS优化、SEO反垃圾链接策略和批量迁移SQL一次讲透,覆盖企业站日常维护全场景。 - 关键词:ASPCMS标签,ASPCMS模板,ASPCMS友情链接,linklist标签,友情链接SEO > **TLDR**:摘要:ASPCMS的友情链接调用,先得懂AspCms_Friendlink底层数据表。本文给出linklist标签的七种写法——文字链、图片链、混合调用与全部链接的高级用法,讲清num与order参数、用if判断做混合调用,再附六步排错SOP、loading懒加载与CLS优化、反垃圾链接的SEO策略和批量导入迁移的SQL,覆盖企业站友链维护的全场景。 > 摘要:ASPCMS的友情链接调用,先得懂AspCms_Friendlink底层数据表。本文给出linklist标签的七种写法——文字链、图片链、混合调用与全部链接的高级用法,讲清num与order参数、用if判断做混合调用,再附六步排错SOP、loading懒加载与CLS优化、反垃圾链接的SEO策略和批量导入迁移的SQL,覆盖企业站友链维护的全场景。 保哥从2010年前后开始接触ASPCMS,那会儿国内做企业站的朋友十有八九都在用它。直到现在保哥手里还有几个老客户的网站跑在ASPCMS上,每次帮他们维护时,最常被问到的就是友情链接怎么调出来、为什么我加的链接不显示、想要图片链接和文字链接同时存在该怎么写。 这篇文章把保哥这十几年踩过的坑、写过的标签、调试过的模板全部整理出来,包括底层数据表结构、五种调用模板写法、缓存与排错SOP、SEO最佳实践,希望对还在维护ASPCMS站点的朋友有帮助。 ## ASPCMS 友情链接系统的底层逻辑 要把标签用对,先得理解ASPCMS的友情链接是怎么组织的。后台内容管理到友情链接里的每一条记录,本质上是一行存在 AspCms_Friendlink 表里的数据。这张表里几个核心字段决定了前台能不能调出来: - linkType:链接类型,1代表文字链接,2代表图片链接。 - groupID:分组编号,对应后台友情链接分类里设置的分类。 - linkName:链接名称,文字链接显示的就是它。 - linkUrl:跳转地址。 - linkPic:图片链接的图片路径,文字链接此字段为空。 - isLock:是否审核通过,前台只调显示已审核的记录。 - Sort:排序值,数字越小越靠前。 - addTime:添加时间,可作为按时间排序的依据。 保哥的经验是,做ASPCMS项目时千万不要把所有链接都丢到默认分组里,一定要在后台先建好分组,比如合作伙伴、行业站点、友情链接、底部链接,前台调用时按 group=N 区分。这样后期客户自己加链接也不会乱。 从SEO角度看,友情链接区块的位置和数量直接影响首页权重外溢。保哥的标准配比是:首页底部不超过20条友情链接,超过的全部移到独立的"友情链接页",并对该页加 noindex,follow 元标签防止稀释首页权重。 ## 文字友情链接的标准调用写法 文字链接是最常用的形式,下面这段是ASPCMS默认模板里保哥反复用过的写法: {aspcms:linklist type=font group=1} <li><a href="[linklist:link]" target="_blank">[linklist:name]</a></li> {/aspcms:linklist} 这里要解释几个关键点: 第一,type=font 表示只调文字链接,对应数据库里 linkType=1 的记录。如果你后台明明加了链接前台却不显示,第一件事就是检查这个type是不是写错了,比如把 font 写成 text 是不行的。 第二,group=1 是分组ID,对应后台分类里的编号。后台第一个分类默认是1,第二个是2,依此类推。保哥习惯把数字直接写死在模板里,但如果你想做成可配置的,可以用ASPCMS的全局变量或者直接传参。 第三,[linklist:link] 和 [linklist:name] 是ASPCMS的字段占位符。每循环一条记录,这两个会被替换成对应数据库字段的值。常用的占位符还有 [linklist:pic](图片地址)、[linklist:intro](链接简介)、[linklist:sort](排序值)、[linklist:addtime](添加时间)。 保哥实际项目里更喜欢这样写,配合上简介当title属性,对SEO友好一点: {aspcms:linklist type=font group=1} <li> <a href="[linklist:link]" target="_blank" rel="nofollow noopener" title="[linklist:intro]"> [linklist:name] </a> </li> {/aspcms:linklist} 加 rel="nofollow" 这一步很多人会漏。友情链接如果不加nofollow,等于把自己网站的权重白白送出去,特别是当你的链接对象不是同等量级的站点时,这个细节一定要注意。noopener 则是防止新窗口打开后劫持父页面的安全做法(reverse tabnabbing 攻击的标准防御)。 ## 图片友情链接的调用与样式控制 图片链接适合放在底部展示合作伙伴LOGO这种场景。标准写法是这样: {aspcms:linklist type=pic group=2} <li> <a href="[linklist:link]" target="_blank"> <img src="[linklist:pic]" alt="[linklist:name]" width="100" height="33" /> </a> </li> {/aspcms:linklist} 保哥要特别强调几个反复看到客户站点出问题的点: 首先,alt属性必须填,而且要有意义。保哥见过太多模板里直接写死 alt="友情链接" 或者干脆不写,这对SEO是浪费。用 [linklist:name] 自动取链接名称,每张图片就有了不同的alt文字 (https://zhangwenbao.com/2025-image-seo-alt-text-risk-optimization.html)。Google对图片alt的语义理解能力越来越强,alt写得好的图片会出现在Google Images里带来额外流量。 其次,inline样式能少写就少写。原来很多ASPCMS老模板里会写 style="border: 1px solid #D6EAF1;" 这种内联样式,建议全部抽到CSS里: .friend-links img { border: 1px solid #D6EAF1; display: block; max-width: 100%; height: auto; object-fit: contain; transition: opacity 0.2s ease; } .friend-links a:hover img { opacity: 0.85; } 最后,width和height属性要保留,浏览器会用这两个值预先分配空间,避免页面加载时的布局抖动(CLS),这是Google Core Web Vitals (https://zhangwenbao.com/core-web-vitals-ai-search-industry-benchmark.html)里的一个核心指标。CLS分数超过0.1就会被Google判定为差,影响排名。 对于2026年的最佳实践,保哥推荐再加上 loading="lazy" 和 decoding="async" 两个属性: <img src="[linklist:pic]" alt="[linklist:name]" width="100" height="33" loading="lazy" decoding="async" /> 友情链接通常在页面底部,懒加载能显著降低首屏请求数,对Largest Contentful Paint指标有帮助。 ## 混合调用与全部链接的高级用法 实际项目里经常有这样的需求:底部既要显示文字链接又要显示图片链接,或者某个分组的所有链接不分类型一起调出来。 如果要调一个分组下的全部链接(不区分图片或文字),把 type 属性去掉,或者写成 type=all: {aspcms:linklist group=1} <li> {if:[linklist:pic]!=""} <a href="[linklist:link]" target="_blank"> <img src="[linklist:pic]" alt="[linklist:name]" /> </a> {else} <a href="[linklist:link]" target="_blank">[linklist:name]</a> {end if} </li> {/aspcms:linklist} 这段里用了ASPCMS的条件标签 {if:},根据 [linklist:pic] 是否为空来判断当前是图片链接还是文字链接,输出不同的HTML结构。这种写法在保哥经手的项目里用得最多,因为它把判断逻辑放在模板里,后台运营人员不需要懂代码,只要在后台传图片就自动变成图片链接,不传图片就是文字链接。 如果要按数量限制,加 num 参数: {aspcms:linklist type=font group=1 num=10} <li><a href="[linklist:link]" target="_blank">[linklist:name]</a></li> {/aspcms:linklist} num=10 就是最多输出10条。配合后台的排序值,可以精准控制首页只展示最重要的几个链接。 更进阶的用法是用 order 参数控制排序方式: <!-- 按添加时间倒序 --> {aspcms:linklist type=font group=1 order=time num=10} <li><a href="[linklist:link]">[linklist:name]</a></li> {/aspcms:linklist} <!-- 按sort字段升序(默认) --> {aspcms:linklist type=font group=1 order=sort num=10} <li><a href="[linklist:link]">[linklist:name]</a></li> {/aspcms:linklist} <!-- 随机排序,每次刷新都不同 --> {aspcms:linklist type=font group=1 order=rnd num=10} <li><a href="[linklist:link]">[linklist:name]</a></li> {/aspcms:linklist} 保哥个人偏爱 order=rnd 随机排序的写法用在大量友情链接展示页,这样所有合作方都有相对公平的展示机会,避免长期被排名靠后的友情伙伴投诉"为啥我家链接总在最下面"。 ## 常见问题排查与调试技巧 保哥这些年帮人调ASPCMS模板,最常遇到的就是标签写对了但前台不显示。排查顺序是这样的: 第一步,检查后台链接是否审核通过。ASPCMS后台添加链接默认是未审核状态,前台不显示。一定要在后台勾选审核通过。 第二步,检查分组ID是否正确。后台友情链接分类里看每个分类左边的编号,那个才是 group=N 里要填的N。如果你删过分类再新建,编号可能不是1、2、3连续的,会跳号。 第三步,清缓存。ASPCMS有自带的页面缓存机制,模板改了之后前台没变化,去后台系统管理到数据维护到清空缓存点一下。如果是CDN前置,CDN缓存也要刷一下。 第四步,看模板路径。ASPCMS的模板文件一般在 /templates/模板名/html/ 目录下,friend.html或者footer.html里写友情链接调用标签。如果你改的不是当前启用的模板,前台当然不变。怎么确认当前模板?后台系统管理到网站设置里看"模板"这一栏。 第五步,开调试模式。在 /config/AspCms_Config.asp 里把 Application("AspCms_DebugMode") 设为True,错误信息会直接打到前台,方便定位问题。调试完一定要关掉,不然会泄露站点信息。 第六步,直接查数据库。如果以上都没问题,用Access打开 /data/aspcms.mdb(或对应SQL Server),看 AspCms_Friendlink 表里那条记录的 isLock、groupID、linkType 字段值是否符合预期。保哥的经验是80%的"标签不显示"问题最终都能在数据库里看出端倪。 ## 为 SEO 优化的友情链接最佳实践 保哥做了多年SEO,友情链接这块踩过的坑足够写一本书。说几个ASPCMS站点特别容易忽视的点: 第一,不是所有友情链接都要nofollow。同等量级、内容相关的优质站点之间互链是有正向作用的,不需要加nofollow。但如果对方是低质量站、行业不相关、或者你怀疑对方权重比你低很多,加上nofollow更安全。从2026年的Google算法看,PageRank Sculpting 的效果已经被弱化,但nofollow在反垃圾链接判定上仍然重要。 第二,外链一定要 target="_blank" + rel="noopener"。前者是用户体验考虑,后者是安全考虑,两个都不能少。如果你的页面会被嵌入到第三方iframe里,再加一个 rel="noreferrer" 防止referrer泄露。 第三,定期检查死链 (https://zhangwenbao.com/batch-detection-of-site-dead-links.html)。友情链接给久了,对方的站可能挂了或者改版了。死链对自身SEO是负面影响。可以用Screaming Frog或者Ahrefs的Broken Link Checker定期跑一遍,保哥的客户站点是每月一次自动扫描,发现死链立刻在后台标记隐藏。 第四,结构化数据可以加。在友情链接区域外层加一个 <nav aria-label="友情链接">,配合恰当的schema.org标记,搜索引擎能更好理解这个区块的语义。Google会根据nav标签判断这是导航而非正文内容,权重传递的算法会有差异。 第五,警惕"友链买卖"陷阱。某些灰产站点会主动找你换友链,给你的网站带来一两个月的"免费"权重,然后悄悄把链接换成赌博、菠菜、加密货币诈骗站。Google一旦察觉你的友情链接区出现这类站点,整站会被降权甚至K站。保哥的硬规矩:友情链接区的所有链接每月人工核对一次,发现违规站点立刻撤掉。 ## 批量导入与迁移友情链接 如果你接手了一个老站,要把几百条友情链接从老CMS迁移到ASPCMS,逐条在后台添加显然不现实。保哥的做法是直接操作数据库: -- 假设你已经把老站友情链接导出成 CSV -- 字段顺序:name, url, pic, group_id, sort, type LOAD DATA INFILE '/path/to/links.csv' INTO TABLE AspCms_Friendlink FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY '\n' (linkName, linkUrl, linkPic, groupID, Sort, linkType) SET isLock = 1, addTime = NOW(); 注意 isLock=1 是审核通过状态,导入后前台才能直接显示。如果导入后前台还是不显示,按上一节的排查清单逐项检查。 如果是Access版本的ASPCMS,可以用Microsoft Access直接打开 aspcms.mdb,把CSV粘贴进 AspCms_Friendlink 表的对应字段。建议导入前先备份mdb文件,导入后逐条抽样验证。 ## 常见问题解答 ## ASPCMS后台添加了友情链接,但前台一直不显示,怎么办? 按顺序排查:先确认后台链接是审核通过状态;然后检查模板里 group=N 的 N 是否对应到该链接所在的分类编号;再清一次系统缓存;最后确认你修改的是当前启用模板的文件。九成以上的不显示问题都在这四步里。如果都查过还是不显示,最后一招是用Access直接打开 aspcms.mdb 看 AspCms_Friendlink 表里那条记录的 isLock、groupID、linkType 字段值是否符合预期。 ## 能不能同时调出多个分组的友情链接? ASPCMS原生标签的 group 参数只接受单个分组ID。如果要调多个分组,可以写两段独立的 aspcms:linklist 标签,分别指定不同的 group。或者修改 /inc/AspCms_LinkAction.asp 里的查询逻辑支持多分组(不建议,升级时会被覆盖)。最干净的做法是在后台把需要合并的分组下的链接全部移动到一个新分组里,然后用一个标签调用。 ## 友情链接按什么顺序显示?怎么调整? 默认按 Sort 字段升序排列,数字越小越靠前。后台编辑链接时有排序字段,把重要的链接设成1、2、3,次要的设成99或者更大就行。也可以通过 order 参数控制,比如 order=time 按添加时间排序、order=rnd 随机排序。保哥推荐用 order=rnd 配合 num 限制条数,既保证视觉新鲜感,又不让后台运营每次都要手动调sort值。 ## 调出来的链接太多想做分页,可以吗? 友情链接通常不分页,一般用 num=N 限制显示数量。如果真的需要分页(比如做友情链接展示页),需要自己写ASP代码查询 AspCms_Friendlink 表配合ASPCMS的分页函数 getPager,原生 aspcms:linklist 标签不支持分页参数。保哥的实战做法是写一个独立的friend_list.asp页面,用ASP原生代码做分页和搜索,把这个页面伪静态 (https://zhangwenbao.com/tools/rewrite-generator.php)成 /friends/index.html 走SEO。 ## 怎么给不同分组的友情链接设置不同的样式? 最简单的做法是在外层包一个带分组标识的class名:用 div class=friend-group-1 包第一组,friend-group-2 包第二组,然后CSS里分别针对每个class写样式。也可以用 [linklist:groupid] 占位符(如果你的ASPCMS版本支持)拿到当前链接的groupID,配合data属性输出到HTML里再用CSS选择器命中。如果你的ASPCMS版本不支持这个占位符,需要修改 AspCms_LinkAction.asp 增加输出。 ## 友情链接出现重复显示怎么办? 三种常见原因:1)后台同一条链接被重复添加,去 AspCms_Friendlink 表用 SELECT linkName, COUNT(*) FROM AspCms_Friendlink GROUP BY linkName HAVING COUNT(*) > 1 找出重复项;2)模板里同一段 aspcms:linklist 被include了两次(检查 footer.html 是否被重复include);3)缓存导致旧版本和新版本同时显示,清缓存解决。保哥见过最离谱的一次是模板继承链上有3层都include了friend模块,结果首页底部出现了18条相同链接。 ## ASPCMS 友情链接标签和 DedeCMS、PHPCMS 的语法有什么区别? 三家都是循环标签的设计,但语法各有特色。DedeCMS用 dede:flink 标签,参数风格类似 row=10 type=text;PHPCMS用 pc:link 标签,参数是XML风格的 num=10 catid=1;ASPCMS用 aspcms:linklist 加大括号包裹的写法。保哥的经验是三家学一家就行,理解了循环、参数、占位符三个概念,看到陌生CMS也能很快上手。最大的差异是DedeCMS和PHPCMS支持MySQL,ASPCMS默认是Access,性能上限低一些。 ## 升级ASPCMS版本会影响我的友情链接模板吗? 取决于升级跨度。小版本升级(比如2.7到2.7.x)一般不影响标签语法。大版本升级(比如2.x到3.x)有可能调整字段名或增减参数,升级前一定要在测试环境跑通模板再上线。保哥的做法是用 git 管理 templates 目录,每次升级前打 tag,升级后逐项对比模板渲染结果,发现差异先在测试环境修好再合到生产。从2018年开始ASPCMS官方更新就很慢,大部分客户站点都不再升级,所以这个问题在2026年的实际场景里反而不那么突出。 ## ASPCMS模板标签怎么调用?站点、导航、列表、详情、分页速查 - URL:https://zhangwenbao.com/aspcms-labels-calling-instructions.html - 分类:ASPCMS教程 - 发布:2017-01-07 | 更新:2026-06-02 - 摘要:ASPCMS模板标签速查手册:覆盖站点全局变量、多级导航、新闻产品图片下载四大列表、详情页字段、分页面包屑、留言板和友情链接,再讲清默认URL规则、IIS伪静态改造、模板目录结构与开发顺序,以及停更后的安全加固建议。 - 关键词:ASPCMS标签,ASPCMS模板,Typecho SEO,技术SEO,ASPCMS > **TLDR**:摘要:这是一份ASPCMS模板标签速查手册,照着就能搭企业站。本文先讲模板架构与变量作用域,再逐类列出站点全局信息、多级导航菜单、news与product与pic与down四大列表、详情页字段访问、分页条与面包屑、留言板gbook、友情链接和条件判断标签的用法,并讲清默认URL规则与IIS伪静态改造、模板目录结构与开发顺序,以及停更后的安全加固。 > 摘要:这是一份ASPCMS (https://zhangwenbao.com/aspcms-calls-the-link-label.html)模板标签速查手册,照着就能搭企业站。本文先讲模板架构与变量作用域,再逐类列出站点全局信息、多级导航菜单、news与product与pic与down四大列表、详情页字段访问、分页条与面包屑、留言板gbook、友情链接和条件判断标签的用法,并讲清默认URL规则与IIS伪静态改造、模板目录结构与开发顺序,以及停更后的安全加固。 ASPCMS 是国内一套基于 ASP 的轻量企业建站系统,2010 年前后非常流行。它的模板开发模型采用一种类似 Smarty 的标签语法({aspcms:xxx}),开发者只要写好 HTML 框架、把这些标签塞到对应位置就能生成完整站点。但 ASPCMS 官方文档常年没更新、社区资料分散在论坛各处,导致很多接手老模板的开发者卡在"忘记某个调用怎么写"的反复 Google 上。本文把所有常用的 ASPCMS 模板标签按"作用域 → 列表 → 详情 → 工具"的层级整理成一份完整的速查手册,并补充两类实战内容:(1) 真实模板代码片段示例;(2) 在 IIS / Windows Server 老环境上 ASPCMS 模板调试常见踩坑。覆盖 ASPCMS 2.x 与 3.x 主流分支。 ## ASPCMS 模板架构与变量作用域基础 ## 模板目录结构 典型的 ASPCMS 模板目录在站点根 /Templates/ 下,每个子目录是一套主题: /Templates/default/ - index.html (首页模板) - about.html (单篇文章模板) - newslist.html (新闻列表模板) - news.html (新闻详情模板) - productlist.html (产品列表模板) - product.html (产品详情模板) - piclist.html, pic.html - downlist.html, down.html - gbook.html (留言板模板) - head.html, foot.html, side.html (辅助片段) - css/, js/, images/ ASPCMS 路由会根据访问的 URL 决定使用哪个模板:访问 /news/?1_5.html 会渲染 news.html,/newslist/?1_1.html 会渲染 newslist.html,依此类推。 ## 标签语法总览 ASPCMS 把标签分三类: - 单行变量:{aspcms:sitetitle} 这种直接输出当前作用域里某个变量值。 - 循环块:{aspcms:newslist size=15}...{/aspcms:newslist} 这种成对出现的标签,中间放循环模板。 - 条件判断:{if:条件}...{end if},类似 if/else 的逻辑控制。 循环块内部用方括号语法访问当前迭代项的字段:[newslist:title]、[newslist:link]。这些方括号变量只在对应循环块内有效,离开块就识别不到。 ## 变量作用域三级 ASPCMS 的作用域由外到内三层: - 全局站点变量:{aspcms:sitetitle} 等以 aspcms 开头的单行标签,任何模板任何位置都能用。 - 当前页面变量:{aspcms:sortname}、{aspcms:sortid}、{aspcms:parentsortid} 等,在列表页或详情页有意义,首页通常为空。 - 循环局部变量:[newslist:title] 等方括号变量,只在 {aspcms:newslist}...{/aspcms:newslist} 块内有意义。 理解这三层是写出来的标签能否正确显示数据的关键——比如在首页直接写 [news:title] 不在循环块里,结果就是空字符串,不报错但前端啥也没有。 ## 站点全局信息标签 ## 基础信息 这一组标签从后台"系统设置"读取,在 head.html 和 foot.html 里高频使用: 标签 | 含义 | 典型用法 | {aspcms:sitepath} | 站点根路径(适配子目录部署) | 所有静态资源路径前缀 | {aspcms:languagepath} | 多语言版本路径 | 多语言站点根 | {aspcms:siteurl} | 站点完整 URL(含协议) | 分享、canonical | {aspcms:sitelogo} | LOGO 图片相对路径 | head 里 img src | {aspcms:sitetitle} | 站点标题 | head 里 title 标签 | {aspcms:additiontitle} | 附加标题(栏目分页时拼接) | title 拼接 | {aspcms:sitekeywords} | 站点 meta keywords | head meta | {aspcms:sitedesc} | 站点 meta description | head meta | {aspcms:defaulttemplate} | 当前主题目录名 | 静态资源前缀 | {aspcms:copyright} | 版权信息 | foot 版权区 | ## 公司联系信息 从后台"公司信息"读取,常用在底部信息栏和联系页: 标签 | 含义 | {aspcms:companyname} | 公司名称 | {aspcms:companyaddress} | 公司地址 | {aspcms:companypostcode} | 邮政编码 | {aspcms:companycontact} | 联系人 | {aspcms:companyphone} | 电话号码 | {aspcms:companymobile} | 手机号码 | {aspcms:companyfax} | 公司传真 | {aspcms:companyemail} | 电子邮箱 | {aspcms:companyicp} | 备案号 | {aspcms:statisticalcode} | 统计代码(百度统计、CNZZ) | ## head.html 完整范例 <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>{aspcms:sitetitle}{aspcms:additiontitle}
    {aspcms:sitetitle}
    ## 导航与多级菜单 ## navlist 一级导航 所有顶级栏目的循环输出: {aspcms:navlist type=0} [navlist:name] {/aspcms:navlist} type=0 表示从根级开始。type=4 等数字表示从特定父分类下取子分类,等于"固定分类列表"。 ## subnavlist 二级及以下 嵌套在 navlist 内: {aspcms:navlist type=0}
  • [navlist:name] {aspcms:subnavlist type=[navlist:sortid]} [subnavlist:name] {/aspcms:subnavlist}
  • {/aspcms:navlist} ## 当前位置高亮 列表页或详情页里高亮当前所在分类,用 if 标签判断 sortid: {aspcms:navlist type=0} [navlist:name] {/aspcms:navlist} ## 栏目类型 navlist 返回的栏目数据 type 字段告诉你这个栏目是什么形态,常用于决定展示样式: type 值 | 栏目形态 | 1 | 单篇文章(about) | 2 | 文章列表(newslist) | 3 | 产品列表(productlist) | 4 | 下载列表(downlist) | 5 | 招聘列表 | 6 | 相册列表(piclist) | 7 | 外部链接 | ## 列表标签:news / product / pic / down 四大类 ## 新闻列表 newslist 输出当前分类下的新闻列表: {aspcms:newslist size=15 order=time}
  • [newslist:title len=40] [newslist:date style=yy-m-d] [newslist:visits]
  • {/aspcms:newslist} 参数说明: - size:每页数量,默认 10。 - order:排序字段,可选 id(按 ID)、time(按时间)、visits(按浏览量)。 - [newslist:title len=40]:标题截断到 40 字符。 - [newslist:date style=yy-m-d]:日期格式,可选 yy-m-d 输出 2024-01-01、y-m-d 输出 24-01-01、m-d 输出 01-01。 ## 产品列表 productlist {aspcms:productlist size=20 order=time} {/aspcms:productlist} productlist 比 newslist 多了 [productlist:pic],是产品的封面图(通常是缩略图路径)。 ## 图片列表 piclist {aspcms:piclist size=20 order=time} [piclist:title] {/aspcms:piclist} ## 下载列表 downlist {aspcms:downlist size=15 order=time}
  • [downlist:title len=50] [downlist:date style=yy-m-d] [downlist:visits]
  • {/aspcms:downlist} ## 首页跨分类调用 list 标签默认只取当前分类的数据,要在首页跨分类取数据用 {aspcms:news}、{aspcms:product}、{aspcms:content} 这种"非 list 后缀"标签,加 sort=分类ID 参数: {aspcms:news sort=2 num=5}
  • [news:title len=20] [[news:date style=m-d]]
  • {/aspcms:news} {aspcms:product sort=4 num=15 order=isrecommend}
  • [product:title]
  • {/aspcms:product} order 参数除了 time/id/visits 还可以是 isrecommend(推荐排序)、top(置顶排序)。 ## 详情页字段访问 ## 单篇文章详情 about about.html 模板里直接用 [about:xxx] 不需要循环包裹,因为单篇文章的作用域已经在详情页范围内自动激活: 字段 | 含义 | [about:info] | 正文 HTML | [about:desc] | 描述(前 100 字摘要) | ## 新闻详情 news 字段 | 含义 | [news:title] | 新闻标题 | [news:desc] | 描述(前 100 字) | [news:source] | 来源 | [news:date] | 发布日期 | [news:visits] | 浏览量 | [news:info] | 正文 HTML | ## 产品详情 product product 比 news 多了 [product:pic](封面图)。其他字段(title、desc、source、date、visits、info)一致。 ## 图片详情 pic 和下载详情 down pic 详情字段和 product 类似(pic、title、desc、source、date、visits、info)。down 详情多了 [down:downurl](下载地址)。 ## 详情页前后篇导航
    上一篇:{aspcms:prev} 下一篇:{aspcms:next}
    ## 详情正文分页 正文超长想分页时,在编辑器里手动插入分页符,模板里用 {aspcms:page} 输出分页条。 ## 分页条 pagenumber 列表页底部的分页器: 不同列表对应不同的 pagenumber 标签: - [newslist:pagenumber len=5] 新闻列表 - [productlist:pagenumber len=5] 产品列表 - [downlist:pagenumber len=5] 下载列表 - [piclist:pagenumber len=5] 图片列表 len 参数是页码显示数量。len=5 表示同时显示 5 个页码(如 1 2 3 4 5)。 ## 当前分类与位置标签 ## 当前分类信息 标签 | 含义 | {aspcms:sortname} | 当前分类名称 | {aspcms:sortid} | 当前分类 ID | {aspcms:parentsortid} | 当前分类的父分类 ID | ## 面包屑:position position 块会自动迭代当前页面的祖先链路(首页 > 一级 > 二级 > 当前),开发者只要写好"一级条目"的样式即可。 ## 侧边栏当前栏目下的子栏目 {aspcms:navlist type={aspcms:parentsortid}}
  • [navlist:name]
  • {/aspcms:navlist} 把 navlist 的 type 设置为 {aspcms:parentsortid},就只输出当前栏目同级的兄弟栏目(用于侧边导航高亮当前位置)。 ## 留言板 gbook 与 gbooklist ## 调用留言表单
    {aspcms:gbook}
    这一行会在前端渲染出 ASPCMS 默认的留言表单(标题、姓名、内容输入框 + 提交按钮)。表单的样式是后台留言模块的全局样式。 ## 留言列表 {aspcms:gbooklist size=10 order=time}

    [gbooklist:title]

    [gbooklist:name] · [gbooklist:wdate style=y-m-d]

    [gbooklist:winfo]

    {if:[gbooklist:status]}

    管理员回复 · [gbooklist:rdate style=y-m-d]

    [gbooklist:rinfo]

    {end if}
    {/aspcms:gbooklist} 字段对照: - [gbooklist:title] 留言标题 - [gbooklist:name] 留言人姓名 - [gbooklist:wdate] 留言时间 - [gbooklist:winfo] 留言内容 - [gbooklist:status] 是否已回复(用于 if 判断) - [gbooklist:rdate] 回复时间 - [gbooklist:rinfo] 回复内容 ## 链接规则与 URL 解析 ## ASPCMS 默认 URL 格式 页面类型 | URL 形式 | 单篇文章 | about/?sortid.html | 文章列表 | newslist/?sortid_page.html | 文章详情 | news/?sortid_id.html | 产品列表 | productlist/?sortid_page.html | 产品详情 | product/?sortid_id.html | 图片列表 | piclist/?sortid_page.html | 图片详情 | pic/?sortid_id.html | 下载列表 | downlist/?sortid_page.html | 下载详情 | down/?sortid_id.html | 留言板 | gbook/ | 其中 sortid 是栏目 ID,id 是内容 ID,page 是当前页码。 ## 静态资源路径前缀 引用 CSS、JS、图片等静态资源时必须用模板路径前缀,否则部署到子目录后 404: ## 站内链接路径前缀 所有站内 a 链接的 href 加 /{aspcms:sitepath} 前缀: 查看更多产品>> ## SEO 友好 URL 改造 ASPCMS 默认的 URL 带 ? 参数对 SEO 不友好。可以在 IIS 的 web.config 里配置 URL Rewrite 把 news/?1_5.html 重写为 /news/1/5.html: 同时模板里的 [newslist:link] 输出的 URL 也要改写——这需要修改 ASPCMS 的链接生成逻辑(Plus/Class/Cls_BLL.asp 之类的核心文件)。难度较高,但可显著提升 SEO 表现。 ## 模板片段调用与辅助模板 ## 头部 / 底部片段 {aspcms:top} {aspcms:foot} ## 侧边栏等任意片段 除了 head/foot,还有任意命名的辅助模板。在主模板里通过 {aspcms:template src=xxx.html} 调用: 这种写法等于"模板 include",把一个共用片段复用到多个页面。 ## 友情链接 linklist ## 图片型友情链接 ## 文字型友情链接 ## 全部友情链接 {aspcms:linklist type=all} [linklist:name] {/aspcms:linklist} SEO 提示:友情链接默认不带 nofollow,权重会传递给对方。如果是临时合作或不信任对方站点,记得手动给链接加 rel="nofollow" 或在后台批量设置。 ## 条件判断与逻辑控制 ## if 标签基础 {if:[navlist:sortid]={aspcms:sortid}} class="active" {end if} 条件支持的运算符:=(等于)、<>(不等)、>、<、>=、<=。 ## if-else 嵌套 ASPCMS 的 if 没有原生 else 分支。常见做法是连续两个 if: {if:[navlist:type]=2} {end if} {if:[navlist:type]=3} {end if} 更复杂的逻辑(多分支、嵌套循环条件)一般要在后端核心文件改 ASP 代码,模板层面表达力有限。 ## 实战:从零搭一个 ASPCMS 模板的目录结构 给一个完整最小模板的文件清单: /Templates/mytheme/ ├── head.html # 共用头部 + nav ├── foot.html # 共用底部 + 版权 + 统计代码 ├── side.html # 侧边栏(联系信息 + 推荐产品) ├── index.html # 首页(包 head/foot/side + 首页内容) ├── about.html # 单篇模板(关于我们 / 联系我们等) ├── newslist.html # 新闻列表 ├── news.html # 新闻详情 ├── productlist.html # 产品列表 ├── product.html # 产品详情 ├── piclist.html ├── pic.html ├── downlist.html ├── down.html ├── gbook.html # 留言板 ├── search.html # 搜索结果 ├── 404.html # 404 页面 └── /css/style.css └── /js/main.js └── /images/logo.png 开发顺序建议: - 先写 head.html 和 foot.html,确认全局变量都能正确输出。 - 写 index.html,重点是各种 list 标签跨分类调用。 - 写 newslist.html / productlist.html / piclist.html,确保分页器正常工作。 - 写 news.html / product.html,详情字段的访问与前后篇导航。 - 写 gbook.html、search.html、404.html。 - 测试所有页面在 IE9+ / Edge / Chrome / Firefox / 移动端浏览器的表现。 ## 常见踩坑与维护建议 ## 编码问题:模板文件必须 GBK 还是 UTF-8 ASPCMS 早期版本默认 GBK 编码(中文 Windows 服务器友好),新版本支持 UTF-8。模板文件的编码必须和 ASPCMS 后台设置一致——不一致就会乱码。Windows 记事本默认保存 ANSI(GBK),用 VS Code、Notepad++ 时务必显式选 UTF-8 不带 BOM。 ## IIS 必须启用 ASP 经典模式 ASPCMS 是 ASP 不是 ASP.NET。Windows Server 2019 / 2022 默认不装 ASP 模块,需要在"服务器管理器 → 添加角色 → Web 服务器 (IIS) → 应用程序开发"里勾选 ASP。否则访问 .asp 文件会 404 或下载源码。 ## 权限问题:data 目录必须可写 ASPCMS 的数据文件、缓存、上传都在 /data/ 目录。给运行 IIS 进程的用户(IUSR / IIS_IUSRS)赋"修改"权限,否则后台发布文章和上传图片都失败。 ## SQL 注入历史漏洞 ASPCMS 早期版本(2.x)有多个已知 SQL 注入和文件上传漏洞(CVE 列表能查到)。生产环境必须升级到 3.x 最新版本,并加 WAF / nginx 反向代理 (https://zhangwenbao.com/nginx-proxy.html)过滤恶意请求。 ## 移动端适配 ASPCMS 默认模板不响应式。要做手机版可以走两条路:(1) 模板里用 CSS3 媒体查询做响应式适配;(2) 后台启用"手机模板"功能,单独开发 mobile/ 目录的模板,通过 UA 判断切换。 ## 静态化部署 ASPCMS 后台支持把动态页面生成静态 HTML("系统设置 → 静态页面生成")。生成后通过 IIS 直接出静态文件,性能高且 SEO 友好。但生成的 HTML 文件体积大、增量更新慢,适合内容更新 (https://zhangwenbao.com/old-blog-content-update-merge-delete-seo-sop.html)频次低的企业站。 ## 常见问题解答 ## ASPCMS 现在还有人维护吗 官方 ASPCMS 在 2015 年后基本停止主版本更新,最新公开版本是 ASPCMS 3.0。社区有零散的安全补丁但没有持续更新的 fork。如果是新项目,不建议选 ASPCMS——优先 WordPress / Typecho / DedeCMS / Joomla 这类还在维护的系统。如果是接手老项目,照本文方法读懂模板就能维护下去。 ## ASPCMS 的标签和 DedeCMS 标签能互相迁移吗 不能直接迁移,但思路高度相似。ASPCMS 的 {aspcms:newslist} 大致对应 DedeCMS 的 {dede:arclist},循环字段访问也类似(一个用 [newslist:title],另一个用 [field:title /])。迁移模板时主要是逐个标签找对应替换,工作量不小但不复杂。 ## 怎么把 ASPCMS 模板改成响应式布局 核心是 CSS 改造,标签层面几乎不动。在 head.html 加 viewport meta、在 style.css 用 flex/grid 布局并用媒体查询适配多端。导航在小屏幕折叠成汉堡菜单(用一段 JS 控制 nav 显示隐藏即可)。改造完测试主要分辨率(320 / 375 / 414 / 768 / 1024 / 1440)下的显示效果。 ## 列表页只显示了 10 条数据想要更多怎么改 调整 size 参数即可:{aspcms:newslist size=30 order=time} 改成 30。但要注意单页数据太多影响加载速度,建议 size 控制在 20-50 之间,配合分页器使用。如果是首页推荐位 num 参数:{aspcms:news num=10} 改成 10。 ## list 标签 order 参数除了 time/id/visits 还有哪些值 常用还有 isrecommend(按推荐排序)、top(按置顶排序)。具体支持哪些字段取决于内容表的字段——查看 /Plus/Class/ 下相关 ASP 文件里的 SQL 拼接逻辑可以确认。常见错误:写错排序字段名(比如把 visits 写成 view)会导致 SQL 出错或回退默认排序。 ## position 面包屑里"首页"是写死的还是有标签 "首页"两个字是写死在模板里的,因为 position 块只迭代分类祖先链路不包括根。如果是多语言站点要把"首页"也国际化,可以从语言包变量读:{aspcms:lang_home},前提是在 ASPCMS 后台多语言模块定义了 lang_home 变量。 ## 模板里能写 ASP 原生代码吗 可以但不推荐。ASPCMS 的 .html 模板文件最终被 ASP 引擎处理,可以直接嵌入 <%...%> 段写 VBScript 或 JScript。但这样写出来的模板可读性差、容易和 ASPCMS 标签解析冲突、维护成本高。建议把所有动态逻辑都用 ASPCMS 标签实现,必须用 ASP 时也限制在很小范围。 ## ASPCMS 站点想做 SEO 优化主要从哪几个方向入手 四个方向:(1) URL 改造:从 ?sortid_id.html 改成 /category-name/article-id.html 这种伪静态 (https://zhangwenbao.com/discuz-portal-list-rewrite.html)形式;(2) 元信息:head.html 里 title、description、keywords 用文章本身字段而非全局站点字段(详情页用 [news:title] 等);(3) 结构化数据:在详情页输出 Article schema JSON-LD;(4) 站点速度:开启 IIS 静态压缩、合并 CSS/JS、图片转 WebP。 ## ASPCMS 后台访问慢怎么排查 三个方向:(1) /data/ 目录文件量过大(特别是 cache 和缓存日志),定期清理;(2) Access 数据库太大(/data/aspcms.mdb 超过 50MB 性能急降),考虑迁到 SQL Server;(3) IIS 应用池回收设置不合理,设置定时回收避免内存泄漏导致响应变慢。 ## 升级 ASPCMS 大版本后模板不兼容怎么办 主版本升级(如 2.7 升 3.0)后部分标签语法或字段名会变。建议升级前 git diff 模板文件标签,升级后用一个测试站完整跑一遍 head/index/列表/详情/留言板五个核心场景,发现报错或 404 再定位具体哪个标签没换。可以参考 ASPCMS 官方升级日志(虽然简略但能找到关键变更点)。 ## 总结 ASPCMS 的模板标签设计虽然朴素但很完整:站点全局信息、多级导航、四大列表、详情字段、分页器、面包屑、留言、链接、辅助模板、条件判断都覆盖到了。掌握了本文这份速查后,做一套企业站模板的开发周期通常在 3-7 天(看样式复杂度)。维护他人留下的 ASPCMS 模板时,遇到不熟的标签翻这份手册查表即可。但要清醒:ASPCMS 已停更多年,新项目尽量用现代 CMS;老项目可以维护但要做好安全加固(WAF + 备份 + 漏洞监控)。这份速查的核心价值不是教你"怎么做新 ASPCMS 站",而是让你能在接手老项目时迅速上手不踩坑。