开发主题,首先要会使用freemarker模板引擎

必要说明:

  • 主题开发好了,需要放在 src/main/resources/templates/theme 下,系统启动会自动读取主题目录,然后在后台就可以选择你想要的主题了
  • 如果你不是开发环境,那需要将开发好的或者下载的主题文件夹放在 pybbs.jar 所在目录下的 templates/theme 文件夹下,如果这两个文件夹没有,需要你创建好
  • 开发主题肯定需要引入样式,建议使用 cdnjs.com 的外链,但也有一些对系统内的样式,这个样式文件需要放在 pybbs.jar 目录所在文件夹下的 templates/static/theme/css 文件夹下,js同理

主题目录

主题必备目录有以下几个

  1. simple
  2. ├── comment
  3. ├── tag
  4. ├── topic
  5. └── user

必备的文件有如下

  1. simple
  2. ├── comment
  3. └── edit.ftl
  4. ├── error.ftl
  5. ├── index.ftl
  6. ├── login.ftl
  7. ├── notifications.ftl
  8. ├── register.ftl
  9. ├── search.ftl
  10. ├── tag
  11. ├── tag.ftl
  12. └── tags.ftl
  13. ├── top100.ftl
  14. ├── topic
  15. ├── create.ftl
  16. ├── detail.ftl
  17. └── edit.ftl
  18. └── user
  19. ├── collects.ftl
  20. ├── comments.ftl
  21. ├── profile.ftl
  22. ├── settings.ftl
  23. └── topics.ftl

注意,上面列出来的文件夹和文件都是必备的

如果你习惯封装,可以跟default主题里一样,把通用的代码块封装成component,放在一个文件夹里(比如 default主题里的组件文件夹就是 components 当然这个不是必须的)

全局对象

通俗点说就是在所有页面里都能取到的数据的对象,有如下几个

对象名描述
model这个对象就是项目中类 BaseModel 的对象,所以使用这个对象可以调用BaseModel类中的所有方法
_user这个对象是用户在登录或者注册成功后,将当前用户的对象存放在Session中的对象,只有在用户登录后才能获取到
site这个对象就是后台系统配置中的那一堆东西
i18n如果开发主题里要适配上国际化,可以使用这个对象来获取一些国际化菜单的不同语言的不同值

model对象内的方法

  1. String formatDate(Date date);
  2. String formatContent(String content);
  3. Set<String> getUpIds(String upIds);
  4. boolean isEmpty(String txt);

site对象中的属性

在页面里取site里的属性方法 ${site.name!}

属性的类型全都是 String,可根据自己需要将值转成 int 或者 boolean

属性描述
admin_remember_me_max_age登录后台记住我功能记住时间,单位:天
base_url网站部署后访问的域名,注意这个后面没有 "/"
comment_layer评论盖楼形式显示
cookie_domain存cookie时用到的域名,要与网站部署后访问的域名一致
cookie_max_agecookie有效期,单位秒,默认1周
cookie_name存cookie时用到的名称
intro站点介绍
name站点名称
page_size分页每页条数
topic_view_increase_interval同一个用户浏览同一个话题多长时间算一次浏览量,默认10分钟,单位秒(只有当配置了redis才会生效)
theme系统主题
mail_host邮箱的smtp服务器地址
mail_password发送邮件的邮箱密码
mail_username发送邮件的邮箱地址
static_url静态文件访问地址,主要用于上传图片的访问,注意最后有个"/"
upload_avatar_size_limit上传头像文件大小,单位MB,默认2MB
upload_path上传文件的路径,注意最后有个"/"
create_comment_score发布评论奖励的积分
create_topic_score创建话题奖励的积分
delete_comment_score删除评论要被扣除的积分
delete_topic_score删除话题要被扣除的积分
up_comment_score点赞评论奖励评论作者的积分
up_topic_score点赞话题奖励话题作者的积分
redis_hostredis服务host地址
redis_portredis服务端口(默认: 6379)
redis_passwordredis服务密码
redis_timeout网站连接redis服务超时时间,单位毫秒
redis_database网站连接redis服务的哪个数据库,默认0号数据库,取值范围0-15
redis_sslredis服务是否开启认证连接
elasticsearch_hostelasticsearch服务的地址
elasticsearch_portelasticsearch服务的http端口
elasticsearch_index索引的名字
search是否开启搜索功能(如果开启,需要额外启动一个ES服务,并填好ES相关的配置)
oauth_github_client_idGithub登录配置项ClientId
oauth_github_client_secretGithub登录配置项ClientSecret
oauth_github_callback_urlGithub登录配置项回调地址
websocket是否开启websocket功能
websocket_hostwebsocket服务的主机名,这个跟cookie的域名设置成一样的就可以了
websocket_portwebsocket服务的端口,不能跟论坛服务端口一样,其它随便设置

i18n对象中的属性

在页面中获取的方法是 ${i18n.getMessage("index")}

属性描述
index首页
tag标签
search搜索
login登录
github_loginGithub登录
register注册
notification通知
setting设置
logout登出
welcome欢迎您
admin.dashboard仪表盘
admin.topics话题列表
admin.comments评论列表
admin.tags标签列表
admin.users用户列表
admin.permission_config权限中心
admin.admin_users后台用户列表
admin.roles角色列表
admin.permissions权限列表
admin.system_config系统设置

Freemarker自定义标签

pybbs提供了如下几个自定义标签

标签名描述参数返回的对象(类型)
tag_topics话题列表pageNo, tabpage(Page<Map<String, Object>>)
tag_other_topic作者其它话题userId, topicId, limittopics(List)
tag_notifications通知列表userId, read, limitnotifications(List<Map<String, Object>>)
tag_score积分排行limitusers(List)
tag_search搜索结果列表keyword, pageNopage(Page<Map<String, Object>>)
tag_tags标签列表pageNo, pageSizepage(Page)
tag_user_topics用户的话题列表username, pageNo, pageSizetopics(Page<Map<String, Object>>)
tag_user_comments用户的评论列表username, pageNo, pageSizecomments(Page<Map<String, Object>>)
tag_user_collects用户的收藏列表username, pageNo, pageSizecollects(Page<Map<String, Object>>)
tag_topic_comments话题的评论列表topicIdcomments(List)

在标签返回对象里有一些不是定义的model里的对象,而是Map封装的对象,这些map里都有啥呢?

标签 tag_topics 对象中的Map包含的字段

  • Topic t.*: Topic对象里的所有字段
  • username: 用户名
  • avatar: 用户头像

标签 tag_notifications 对象中的Map包含的字段

  • Notification n.*: Notification对象里的所有字段
  • username: 用户名
  • avatar: 用户头像
  • title: 话题标题
  • topicId: 话题ID

标签 tag_search 对象中的Map包含的字段

  • id: 话题ID
  • title: 话题标题
  • content: 话题内容

标签 tag_user_topics 对象中的Map包含的字段

  • Topic t.*: Topic对象里的所有字段
  • username: 用户名
  • avatar: 用户头像

标签 tag_user_comments 对象中的Map包含的字段

  • Comment c.*: Comment对象里的所有字段
  • topicUsername: 话题的用户名
  • commentUsername: 话题的用户名
  • title: 话题标题
  • topicId: 话题ID

标签 tag_user_collects 对象中的Map包含的字段

  • Topic t.*: Topic对象里的所有字段
  • username: 用户名
  • avatar: 用户头像

自定义标签使用

自定义标签用法很简单,不会用的话,可以参考已经存在的主题里的用法,下面说一下首页的 tag_topics 标签的用法

  1. <@tag_topics pageNo=pageNo tab=tab>
  2. // tag_topics 里的两个参数都是从controller里传过来的
  3. // 在标签内部就可以拿到自定义标签返回的对象了,比如这个标签返回的就一个page对象
  4. <#list page.records as topic>
  5. <p>${topic.title}</p>
  6. </#list>
  7. </@tag_topics>

至于标签里返回的对象都是什么东西,下面介绍,先说说每个路由渲染的页面里都能取出什么东西吧

路由渲染可获取对象

地址类名参数放在model中对象渲染视图文件名
/IndexControllertab, pageNotab, active, pageNoindex.ftl
/top100IndexControllertop100.ftl
/settingsIndexControlleruseruser/settings.ftl
/tagsIndexControllerpageNopageNotag/tags.ftl
/loginIndexControllerlogin.ftl
/registerIndexControllerregister.ftl
/notificationsIndexControllernotifications.ftl
/logoutIndexController重定向到首页
/searchIndexControllerpageNo, keywordpageNo, keywordsearch.ftl
/changeLanguageIndexControllerlang: zh, cn重定向到之前页面首页
/activeIndexControlleremail, code激活成功后重定向到
/user/{username}UserControllerusernamegithubLogin, user, username, oAuthUsers, collectCountuser/profile.ftl
/user/{username}/topicsUserControllerusername, pageNousername, pageNouser/topics.ftl
/user/{username}/commentsUserControllerusername, pageNousername, pageNouser/comments.ftl
/user/{username}/collectsUserControllerusername, pageNousername, pageNouser/collects.ftl
/topic/{id}TopicControlleridcollect, topic, tags, topicUser, collectstopic/detail.ftl
/topic/createTopicControllertagtagtopic/create.ftl
/topic/edit/{id}TopicControlleridtopic, tagstopic/edit.ftl
/topic/tag/{name}TopicControllernametag, pagetag/tag.ftl
/comment/edit/{id}CommentControlleridcomment, topiccomment/edit.ftl
/common/captchaCommonController响应的是一张图片验证码的流
/oauth/githubOAuthController重定向到Github授权页面,授权完成自动回调

对象包含的字段

分页对象 Page

这个对象是Mybatis-Plus里封装的,常用字段有以下几个

  • List records: 查询出来的列表放在这个里面,类型是个List
  • long current: 当前是第几页,从1开始
  • long total: 总条数
  • long pages: 总页数
  • long size: 每页显示条数

用户对象 User

  1. private Integer id;
  2. private String username;
  3. private String telegramName;
  4. private String avatar;
  5. private String password;
  6. private String email;
  7. // 个人网站
  8. private String website;
  9. // 个人简介
  10. private String bio;
  11. private Integer score;
  12. private Date inTime;
  13. private String token;
  14. // 有消息通知是否通过邮箱收取
  15. private Boolean emailNotification;
  16. // 帐号的激活状态
  17. private Boolean active;

话题对象 Topic

  1. private Integer id;
  2. private String title;
  3. private String content;
  4. private Date inTime;
  5. private Date modifyTime;
  6. private Integer userId;
  7. // 评论数
  8. private Integer commentCount;
  9. // 收藏数
  10. private Integer collectCount;
  11. // 浏览数
  12. private Integer view;
  13. // 置顶
  14. private Boolean top;
  15. // 加精
  16. private Boolean good;
  17. // 点赞用户的id英文,隔开的,要计算被多少人点赞过,可以通过英文,分隔这个字符串计算数量
  18. private String upIds;

评论对象 Comment

  1. private Integer id;
  2. private Integer topicId;
  3. private Integer userId;
  4. private String content;
  5. private Date inTime;
  6. private Integer commentId;
  7. // 点赞用户的id
  8. private String upIds;

评论(盖楼)对象 CommentsByTopic

  1. // 话题下面的评论列表单个对象的数据结构
  2. public class CommentsByTopic extends Comment implements Serializable {
  3. private String username;
  4. private String avatar;
  5. // 评论的层级,直接评论话题的,layer即为0,如果回复了评论的,则当前回复的layer为评论对象的layer+1
  6. private Integer layer;
  7. }

通知对象 Notification

  1. private Integer id;
  2. private Integer topicId;
  3. private Integer userId;
  4. // 通知对象ID
  5. private Integer targetUserId;
  6. // 动作: REPLY, COMMENT, COLLECT, TOPIC_UP, COMMENT_UP
  7. private String action;
  8. private Date inTime;
  9. private String content;
  10. // 是否已读
  11. private Boolean read;

授权登录对象 OAuthUser

  1. private Integer id;
  2. // oauth帐号的id
  3. private Integer oauthId;
  4. // 帐号类型,GITHUB, QQ, WECHAT, WEIBO 等
  5. private String type;
  6. // oauth帐号的登录名
  7. private String login;
  8. private String accessToken;
  9. private Date inTime;
  10. // 个人简介
  11. private String bio;
  12. private String email;
  13. // 本地用户的id
  14. private Integer userId;