主题开发教程

模板主题是一个模块,以 CmsTheme 开头,如 CmsThemeBlueCmsThemeGreen 等。

主题模块结构

  1. CmsThemeMyTest
  2. ├── Admin
  3. ├── Controller
  4. └── ConfigController.php 后台配置文件
  5. └── routes.php
  6. ├── Asset 主题资源文件
  7. ├── css
  8. └── theme.css
  9. └── js
  10. └── theme.js
  11. ├── Core
  12. └── ModuleServiceProvider.php 模块核心注册器
  13. ├── Docs 模块文档
  14. ├── doc
  15. └── Manual.md
  16. ├── module
  17. ├── content.md
  18. ├── demo.md
  19. ├── mobilePreview.md
  20. └── preview.md
  21. └── release
  22. └── 1.0.0.md
  23. ├── Provider
  24. └── ThemeSiteTemplateProvider.php 主题注册器
  25. ├── View 模块视图主目录
  26. └── pc 自适应默认为PC
  27. ├── cms
  28. ├── list 列表视图
  29. ├── cases.blade.php
  30. ├── default.blade.php
  31. ├── job.blade.php
  32. ├── news.blade.php
  33. └── product.blade.php
  34. ├── detail 详情视图
  35. ├── cases.blade.php
  36. ├── default.blade.php
  37. ├── job.blade.php
  38. ├── news.blade.php
  39. └── product.blade.php
  40. ├── form 表单视图
  41. └── default.blade.php
  42. ├── page 单页视图
  43. └── default.blade.php
  44. ├── index.blade.php
  45. ├── footer.blade.php
  46. ├── frame.blade.php 模板框架视图
  47. └── header.blade.php
  48. ├── config.json 模块配置文件
  49. └── demo_data.php 演示数据初始化

视图文件优先级

主题的视图文件( .blade.php 结尾)可能出现在多个位置,系统在渲染视图的时候会按照以下优先级查找直到匹配成功:

  1. 启用主题自定义视图目录:如 resources/views/theme/myTest
  2. 启用主题主视图目录:如 module/CmsThemeMyTest/View
  3. 当前模块视图目录:如 module/Cms/View
  4. 系统默认视图目录:如 resources/views/theme/default

举例说明:

当前系统启用了由CmsThemeMyTest主题模块提供的 myTest 主题。

Cms 模块的列表页面调用 $this->view('cms.list.news')返回视图文件,

系统会按照如下顺序进行视图文件的查找:

  • resources/views/theme/myTest/pc/cms/list/news.blade.php
  • module/CmsThemeMyTest/View/pc/cms/list/news.blade.php
  • module/Cms/View/pc/cms/list/news.blade.php
  • resources/views/theme/default/pc/cms/list/news.blade.php

视图数据实体

栏目Cat

  1. {
  2. "id": 5,
  3. "created_at": "2021-11-02 20:53:18",
  4. "updated_at": "2021-12-19 10:03:07",
  5. "pid": 0,
  6. "sort": 0,
  7. "title": "新闻资讯",
  8. "url": "news",
  9. "modelId": 9,
  10. "listTemplate": "news.blade.php",
  11. "detailTemplate": "news.blade.php",
  12. "seoTitle": "11",
  13. "seoDescription": "22",
  14. "seoKeywords": "33",
  15. "icon": "",
  16. "cover": "",
  17. "subTitle": "为广大企业提供更加轻便、高效、经济的人力资源服务",
  18. "bannerBg": "",
  19. "pageTemplate": null,
  20. "formTemplate": null,
  21. "_model": {
  22. "id": 9,
  23. "created_at": "2021-11-02 20:42:42",
  24. "updated_at": "2021-12-19 10:03:07",
  25. "title": "新闻咨询",
  26. "name": "news",
  27. "detailTemplate": "news.blade.php",
  28. "listTemplate": "news.blade.php",
  29. "pageTemplate": null,
  30. "mode": 1,
  31. "formTemplate": null,
  32. "_customFields": []
  33. }
  34. }

内容ContentSimple

  1. {
  2. "id": 102,
  3. "created_at": "2021-12-20 10:54:03",
  4. "updated_at": "2021-12-20 10:54:03",
  5. "catId": 5,
  6. "modelId": 9,
  7. "alias": null,
  8. "title": "2020整体橱柜十大品牌排行榜",
  9. "summary": "这是2020年评选出来的橱柜十大品牌排行榜,小编对这个排行没有意见,只是仁者见仁,智者见智,排行自有一定的道理,至于其中有什么",
  10. "cover": "vendor/image/news-3.jpg",
  11. "postTime": "2021-01-01 00:00:20",
  12. "wordCount": null,
  13. "viewCount": null,
  14. "status": 1,
  15. "commentCount": null,
  16. "likeCount": null,
  17. "isRecommend": 1,
  18. "isTop": null,
  19. "tags": [],
  20. "author": null,
  21. "source": null,
  22. "seoTitle": null,
  23. "seoDescription": null,
  24. "seoKeywords": null,
  25. "_url": "/a/102",
  26. "_day": "2021-01-01"
  27. }

内容Content

  1. {
  2. "id": 102,
  3. "created_at": "2021-12-20 10:54:03",
  4. "updated_at": "2021-12-20 10:54:03",
  5. "catId": 5,
  6. "modelId": 9,
  7. "alias": null,
  8. "title": "2020整体橱柜十大品牌排行榜",
  9. "summary": "这是2020年评选出来的橱柜十大品牌排行榜,小编对这个排行没有意见,只是仁者见仁,智者见智,排行自有一定的道理,至于其中有什么",
  10. "cover": "vendor/image/news-3.jpg",
  11. "postTime": "2021-01-01 00:00:20",
  12. "wordCount": null,
  13. "viewCount": null,
  14. "status": 1,
  15. "commentCount": null,
  16. "likeCount": null,
  17. "isRecommend": 1,
  18. "isTop": null,
  19. "tags": null,
  20. "author": null,
  21. "source": null,
  22. "seoTitle": null,
  23. "seoDescription": null,
  24. "seoKeywords": null,
  25. "_tags": [],
  26. "_data": {
  27. "id": 102,
  28. "created_at": "2021-12-20 10:54:03",
  29. "updated_at": "2021-12-20 10:54:03",
  30. "content": "<p>橱柜生产企业也由94年的20多家发展到现在的3000多家,规模企业100多家,行业前50家销售额占全行业的30%以上。也因此在橱柜行业内涌现出一批优秀的企业和品牌。</p>\n<p>但是关于中国橱柜十大品牌评选的版本却有很多,但是不管是由谁提出的什么版本,关键是要用重要数据说话。以品牌知名度、质量标准、产品研发、生产能力、销售规模、品牌口碑、可持续发展能力等方面综合来评定才有足够说服力。质量标量是一个知名品牌的生命力,产品研发、生产能力、销售规模、可持续发展能力是一个知名品牌的发展力,品牌知名度、品牌口碑是一个知名品牌的影响力。</p>\n<p>2018年从品牌知名度、质量标准、产品研发、生产能力、销售规模、品牌口碑、可持续发展能力等方面综合评定出的中国橱柜十大品牌名单榜中榜上,皮阿诺排列其中,但是,如果单纯以橱柜终端实际网点,实际销售额来评估,皮阿诺凭借700家终端专卖店和售后服务中心可以位列十大橱柜品牌之首,而在新近由腾讯举办的网友“十大橱柜品牌评选”活动中,皮阿诺更是以高票位居三甲。</p>"
  31. }

模型Model

  1. {
  2. "id": 9,
  3. "created_at": "2021-11-02 20:42:42",
  4. "updated_at": "2021-12-19 10:03:07",
  5. "title": "新闻咨询",
  6. "name": "news",
  7. "detailTemplate": "news.blade.php",
  8. "listTemplate": "news.blade.php",
  9. "pageTemplate": null,
  10. "mode": 1,
  11. "formTemplate": null,
  12. "_customFields": [
  13. {
  14. "id": 19,
  15. "created_at": "2021-12-19 15:48:57",
  16. "updated_at": "2021-12-19 15:48:57",
  17. "modelId": 20,
  18. "sort": 1,
  19. "title": "手机",
  20. "name": "phone",
  21. "fieldType": "text",
  22. "fieldData": [],
  23. "isRequired": 0,
  24. "isSearch": 0,
  25. "isList": 0,
  26. "placeholder": null,
  27. "listTemplate": null,
  28. "showTemplate": null,
  29. "maxLength": 100
  30. },
  31. {
  32. "id": 20,
  33. "created_at": "2021-12-19 15:48:57",
  34. "updated_at": "2021-12-19 15:48:57",
  35. "modelId": 20,
  36. "sort": 2,
  37. "title": "姓名",
  38. "name": "name",
  39. "fieldType": "text",
  40. "fieldData": [],
  41. "isRequired": 0,
  42. "isSearch": 0,
  43. "isList": 0,
  44. "placeholder": null,
  45. "listTemplate": null,
  46. "showTemplate": null,
  47. "maxLength": 100
  48. }
  49. ]
  50. }

列表视图

内置变量 cat

当前栏目信息,数据结构结构参考 栏目Cat

内置变量 catChildren

当前栏目的子栏目,为栏目Cat数组,数据结构参考 栏目Cat

内置变量 catRoot

当前栏目的根级栏目视图,数据结构结构参考 栏目Cat

内置变量 catRootChildren

当前栏目的根级栏目视图子栏目,为栏目Cat数组,数据结构参考 栏目Cat

内置变量 catChain

当前栏目从根栏目到当前栏目的链路,为栏目Cat数组,数据结构参考 栏目Cat

内置变量 records

当前栏目数据列表,为ContentSimple数组,数据结构参考 ContentSimple

内置变量 pageHtml

当前列表分页HTML数据

  1. <div class="pages">
  2. <a href="?page=1">1</a>
  3. <span>2</span>
  4. <a href="?page=1">3</a>
  5. </div>

详情视图

内置变量 record

当前显示内容,数据结构参考 内容Content

内置变量 cat

当前栏目信息,数据结构结构参考 栏目Cat

内置变量 catRoot

当前栏目的根级栏目视图,数据结构结构参考 栏目Cat

内置变量 catRootChildren

当前栏目的根级栏目视图子栏目,为栏目Cat数组,数据结构参考 栏目Cat

内置变量 catChain

当前栏目从根栏目到当前栏目的链路,为Cat数组,数据结构参考 Cat

内置变量 model

当前显示内容的模型,数据结构参考 模型Model

单页视图

内置变量 record

当前显示内容,数据结构参考 内容Content

内置变量 cat

当前栏目信息,数据结构结构参考 栏目Cat

内置变量 catRoot

当前栏目的根级栏目视图,数据结构结构参考 栏目Cat

内置变量 catRootChildren

当前栏目的根级栏目视图子栏目,为栏目Cat数组,数据结构参考 栏目Cat

内置变量 catChain

当前栏目从根栏目到当前栏目的链路,为栏目Cat数组,数据结构参考 栏目Cat

表单视图

内置变量 cat

当前栏目信息,数据结构结构参考 栏目Cat

内置变量 catRoot

当前栏目的根级栏目视图,数据结构结构参考 栏目Cat

内置变量 catRootChildren

当前栏目的根级栏目视图子栏目,为栏目Cat数组,数据结构参考 栏目Cat

内置变量 catChain

当前栏目从根栏目到当前栏目的链路,为Cat数组,数据结构参考 Cat

内置变量 model

当前显示内容的模型,数据结构参考 模型Model

CMS操作方法

列表 listCatByUrl

根据栏目URL获取内容列表(不包含副表字段),包含子栏目

  1. \MCms::listCatByUrl($catUrl, $page = 1, $pageSize = 10, $option = [])

返回数据结构

  1. [
  2. {
  3. "id": 1,
  4. "title": "xxx",
  5. // ...
  6. },
  7. // ...
  8. ]

列表 listCat

根据栏目ID获取内容列表(不包含副表字段),包含子栏目

  1. \MCms::listCat($catId, $page = 1, $pageSize = 10, $option = [])

返回数据结构

  1. [
  2. {
  3. "id": 1,
  4. "title": "xxx",
  5. // ...
  6. },
  7. // ...
  8. ]

列表 pageCat

根据栏目ID获取内容列表(不包含副表字段),包含子栏目

  1. \MCms::pageCat($catId, $page = 1, $pageSize = 10, $option = [])

返回数据结构

  1. {
  2. "total": 10,
  3. "records": [
  4. {
  5. "id": 1,
  6. "title": "xxx",
  7. // ...
  8. },
  9. // ...
  10. ]
  11. }

列表 pageCatByUrl

根据栏目URL获取内容列表(不包含副表字段),包含子栏目

  1. \MCms::pageCatByUrl($catUrl, $page = 1, $pageSize = 10, $option = [])

返回数据结构

  1. {
  2. "total": 10,
  3. "records": [
  4. {
  5. "id": 1,
  6. "title": "xxx",
  7. // ...
  8. },
  9. // ...
  10. ]
  11. }

列表 pageCatWithData

根据栏目ID获取内容列表(包含副表字段),不包含子栏目

  1. \MCms::pageCatWithData($catId, $page = 1, $pageSize = 10, $option = [])

返回数据结构

  1. {
  2. "total": 10,
  3. "records": [
  4. {
  5. "id": 1,
  6. "title": "xxx",
  7. // ...
  8. },
  9. // ...
  10. ]
  11. }

列表 pageCatWithDataByUrl

根据栏目URL获取内容列表(包含副表字段),不包含子栏目

  1. \MCms::pageCatWithDataByUrl($catUrl, $page = 1, $pageSize = 10, $option = [])

返回数据结构

  1. {
  2. "total": 10,
  3. "records": [
  4. {
  5. "id": 1,
  6. "title": "xxx",
  7. // ...
  8. },
  9. // ...
  10. ]
  11. }

列表 pageCatsWithData

根据多个栏目ID获取内容列表(包含副表字段),不包含子栏目,多个栏目必须为相同的模型

  1. \MCms::pageCatsWithData($catIds, $page = 1, $pageSize = 10, $option = [])

返回数据结构

  1. {
  2. "total": 10,
  3. "records": [
  4. {
  5. "id": 1,
  6. "title": "xxx",
  7. // ...
  8. },
  9. // ...
  10. ]
  11. }

列表 pageCatWithDataByUrl

根据多个栏目URL获取列表(包含副表字段),不包含子栏目,多个栏目必须为相同的模型

  1. \MCms::pageCatsWithDataByUrl($catUrls, $page = 1, $pageSize = 10, $option = [])

返回数据结构

  1. {
  2. "total": 10,
  3. "records": [
  4. {
  5. "id": 1,
  6. "title": "xxx",
  7. // ...
  8. },
  9. // ...
  10. ]
  11. }

列表 latestCat

根据栏目ID获取最新内容列表(不包含副表字段),包含子目录,

  1. \MCms::latestCat($catId, $limit = 10)

返回数据结构

  1. [
  2. {
  3. "id": 1,
  4. "title": "xxx",
  5. // ...
  6. },
  7. // ...
  8. ]

列表条件检索

列表带查询条件时,需要自定义 $option 参数,对所有列表获取方法均适用

  1. // 精确匹配
  2. $option = [
  3. 'where' => [
  4. 'title' => '阿里巴巴',
  5. 'source' => '网络',
  6. ],
  7. ];
  8. // 复杂匹配
  9. $option = [
  10. 'whereOperate'=>[
  11. // 模糊匹配
  12. ['title','like','%阿里巴巴%'],
  13. // 范围
  14. ['postTime','>=','2021-01-01 00:00:00'],
  15. ]
  16. ];
  17. // 自定义排序
  18. $option = [
  19. 'order'=>[
  20. ['id','desc']
  21. ]
  22. ];
  23. // 列表默认按照以下排序
  24. $option = [
  25. 'order'=>[
  26. ['isTop', 'desc'],
  27. ['isRecommend', 'desc'],
  28. ['postTime', 'desc'],
  29. ]
  30. ];

栏目上一条内容 prevOne

获取上一条记录

  1. \MCms::prevOne($catId, $recordId)

栏目下一条内容 nextOne

获取下一条记录

  1. \MCms::nextOne($catId, $recordId)

友情链接 MPartner::all

按照位置获取所有友情链接数据

  1. \MPartner::all($position = 'home');

导航 MNav:all

按照位置获取所有导航数据

  1. \MNav::all($position = 'home');

轮播 MBanner:all

按照位置获取所有轮播数据

  1. \MPartner::all($position = 'home')

演示数据

一个优秀的模板需要携带完整的演示数据,这样可以方便快捷的让用户快速的看到主题最终效果。

演示数据开启

CMS集成了演示数据初始化填充功能,只需要简单的配置即可完成。

在对应的模板设置页面(如 功能设置 → 模板设置 → CMS开发测试模板),用户点击初始化演示数据,勾选需要初始化的数据,即可完成数据填充。

演示1

演示2

演示数据参考配置

数据参考配置位于模块根目录下的,如 module/CmsThemeMyTest/demo_data.php

  1. <?php
  2. return [
  3. 'tables' => [
  4. 'banner' => [
  5. 'where' => [
  6. 'position' => 'home',
  7. ],
  8. 'records' => [
  9. [
  10. 'type' => \Module\Banner\Type\BannerType::IMAGE,
  11. 'image' => 'vendor/CmsThemeMyTest/image/banner-1.jpg',
  12. ],
  13. // ...
  14. ]
  15. ],
  16. 'news' => [
  17. 'records' => [
  18. [
  19. 'title' => '演示新闻标题',
  20. 'cover' => 'vendor/CmsThemeMyTest/image/news-1.jpg',
  21. 'summary' => '演示新闻描述',
  22. '_data' => [
  23. 'content' => '<p>演示新闻内容</p>',
  24. ]
  25. ],
  26. // ...
  27. ]
  28. ],
  29. 'product' => [
  30. 'records' => [
  31. [
  32. 'title' => '演示产品',
  33. 'cover' => 'vendor/CmsThemeMyTest/image/product-1.jpg',
  34. ],
  35. // ...
  36. ]
  37. ],
  38. 'cases' => [
  39. 'records' => [
  40. [
  41. 'title' => '演示案例',
  42. 'cover' => 'vendor/CmsThemeMyTest/image/cases-1.jpg',
  43. ],
  44. // ...
  45. ]
  46. ],
  47. 'job' => [
  48. 'records' => [
  49. [
  50. 'title' => '演示招聘',
  51. '_data' => [
  52. 'content' => '<p>演示招聘说明</p>',
  53. ]
  54. ]
  55. ]
  56. ],
  57. 'nav' => [
  58. 'where' => [
  59. 'position' => 'head',
  60. ],
  61. 'records' => [
  62. [
  63. 'name' => '产品',
  64. 'link' => modstart_web_url('product'),
  65. ],
  66. // ...
  67. ],
  68. ],
  69. 'info' => [
  70. 'records' => [
  71. 'Cms_HomeInfoImage' => 'vendor/CmsThemeMyTest/image/about.jpg',
  72. 'Cms_HomeInfoTitle' => '演示公司名称',
  73. 'Cms_HomeInfoContent' => '<p>演示公司介绍。</p>',
  74. ]
  75. ],
  76. ],
  77. ];

常用问题

页面标题、关键词、描述调用

  1. @section('pageTitle')页面标题@endsection
  2. @section('pageKeywords')页面关键词@endsection
  3. @section('pageDescription')页面关键词@endsection