开发主题,首先要会使用freemarker模板引擎
必要说明:
- 主题开发好了,需要放在
src/main/resources/templates/theme
下,系统启动会自动读取主题目录,然后在后台就可以选择你想要的主题了 - 如果你不是开发环境,那需要将开发好的或者下载的主题文件夹放在
pybbs.jar
所在目录下的templates/theme
文件夹下,如果这两个文件夹没有,需要你创建好 - 开发主题肯定需要引入样式,建议使用
cdnjs.com
的外链,但也有一些对系统内的样式,这个样式文件需要放在pybbs.jar
目录所在文件夹下的templates/static/theme/css
文件夹下,js同理
主题目录
主题必备目录有以下几个
simple
├── comment
├── tag
├── topic
└── user
必备的文件有如下
simple
├── comment
│ └── edit.ftl
├── error.ftl
├── index.ftl
├── login.ftl
├── notifications.ftl
├── register.ftl
├── search.ftl
├── tag
│ ├── tag.ftl
│ └── tags.ftl
├── top100.ftl
├── topic
│ ├── create.ftl
│ ├── detail.ftl
│ └── edit.ftl
└── user
├── collects.ftl
├── comments.ftl
├── profile.ftl
├── settings.ftl
└── topics.ftl
注意,上面列出来的文件夹和文件都是必备的
如果你习惯封装,可以跟default主题里一样,把通用的代码块封装成component,放在一个文件夹里(比如 default主题里的组件文件夹就是 components 当然这个不是必须的)
全局对象
通俗点说就是在所有页面里都能取到的数据的对象,有如下几个
对象名 | 描述 |
---|---|
model | 这个对象就是项目中类 BaseModel 的对象,所以使用这个对象可以调用BaseModel类中的所有方法 |
_user | 这个对象是用户在登录或者注册成功后,将当前用户的对象存放在Session中的对象,只有在用户登录后才能获取到 |
site | 这个对象就是后台系统配置中的那一堆东西 |
i18n | 如果开发主题里要适配上国际化,可以使用这个对象来获取一些国际化菜单的不同语言的不同值 |
model对象内的方法
String formatDate(Date date);
String formatContent(String content);
Set<String> getUpIds(String upIds);
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_age | cookie有效期,单位秒,默认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_host | redis服务host地址 |
redis_port | redis服务端口(默认: 6379) |
redis_password | redis服务密码 |
redis_timeout | 网站连接redis服务超时时间,单位毫秒 |
redis_database | 网站连接redis服务的哪个数据库,默认0号数据库,取值范围0-15 |
redis_ssl | redis服务是否开启认证连接 |
elasticsearch_host | elasticsearch服务的地址 |
elasticsearch_port | elasticsearch服务的http端口 |
elasticsearch_index | 索引的名字 |
search | 是否开启搜索功能(如果开启,需要额外启动一个ES服务,并填好ES相关的配置) |
oauth_github_client_id | Github登录配置项ClientId |
oauth_github_client_secret | Github登录配置项ClientSecret |
oauth_github_callback_url | Github登录配置项回调地址 |
websocket | 是否开启websocket功能 |
websocket_host | websocket服务的主机名,这个跟cookie的域名设置成一样的就可以了 |
websocket_port | websocket服务的端口,不能跟论坛服务端口一样,其它随便设置 |
i18n对象中的属性
在页面中获取的方法是 ${i18n.getMessage("index")}
属性 | 描述 |
---|---|
index | 首页 |
tag | 标签 |
search | 搜索 |
login | 登录 |
github_login | Github登录 |
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, tab | page(Page<Map<String, Object>>) |
tag_other_topic | 作者其它话题 | userId, topicId, limit | topics(List |
tag_notifications | 通知列表 | userId, read, limit | notifications(List<Map<String, Object>>) |
tag_score | 积分排行 | limit | users(List |
tag_search | 搜索结果列表 | keyword, pageNo | page(Page<Map<String, Object>>) |
tag_tags | 标签列表 | pageNo, pageSize | page(Page |
tag_user_topics | 用户的话题列表 | username, pageNo, pageSize | topics(Page<Map<String, Object>>) |
tag_user_comments | 用户的评论列表 | username, pageNo, pageSize | comments(Page<Map<String, Object>>) |
tag_user_collects | 用户的收藏列表 | username, pageNo, pageSize | collects(Page<Map<String, Object>>) |
tag_topic_comments | 话题的评论列表 | topicId | comments(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 标签的用法
<@tag_topics pageNo=pageNo tab=tab>
// tag_topics 里的两个参数都是从controller里传过来的
// 在标签内部就可以拿到自定义标签返回的对象了,比如这个标签返回的就一个page对象
<#list page.records as topic>
<p>${topic.title}</p>
</#list>
</@tag_topics>
至于标签里返回的对象都是什么东西,下面介绍,先说说每个路由渲染的页面里都能取出什么东西吧
路由渲染可获取对象
地址 | 类名 | 参数 | 放在model中对象 | 渲染视图文件名 |
---|---|---|---|---|
/ | IndexController | tab, pageNo | tab, active, pageNo | index.ftl |
/top100 | IndexController | top100.ftl | ||
/settings | IndexController | user | user/settings.ftl | |
/tags | IndexController | pageNo | pageNo | tag/tags.ftl |
/login | IndexController | login.ftl | ||
/register | IndexController | register.ftl | ||
/notifications | IndexController | notifications.ftl | ||
/logout | IndexController | 重定向到首页 | ||
/search | IndexController | pageNo, keyword | pageNo, keyword | search.ftl |
/changeLanguage | IndexController | lang: zh, cn | 重定向到之前页面首页 | |
/active | IndexController | email, code | 激活成功后重定向到 | |
/user/{username} | UserController | username | githubLogin, user, username, oAuthUsers, collectCount | user/profile.ftl |
/user/{username}/topics | UserController | username, pageNo | username, pageNo | user/topics.ftl |
/user/{username}/comments | UserController | username, pageNo | username, pageNo | user/comments.ftl |
/user/{username}/collects | UserController | username, pageNo | username, pageNo | user/collects.ftl |
/topic/{id} | TopicController | id | collect, topic, tags, topicUser, collects | topic/detail.ftl |
/topic/create | TopicController | tag | tag | topic/create.ftl |
/topic/edit/{id} | TopicController | id | topic, tags | topic/edit.ftl |
/topic/tag/{name} | TopicController | name | tag, page | tag/tag.ftl |
/comment/edit/{id} | CommentController | id | comment, topic | comment/edit.ftl |
/common/captcha | CommonController | 响应的是一张图片验证码的流 | ||
/oauth/github | OAuthController | 重定向到Github授权页面,授权完成自动回调 |
对象包含的字段
分页对象 Page
这个对象是Mybatis-Plus里封装的,常用字段有以下几个
- List records: 查询出来的列表放在这个里面,类型是个List
- long current: 当前是第几页,从1开始
- long total: 总条数
- long pages: 总页数
- long size: 每页显示条数
用户对象 User
private Integer id;
private String username;
private String telegramName;
private String avatar;
private String password;
private String email;
// 个人网站
private String website;
// 个人简介
private String bio;
private Integer score;
private Date inTime;
private String token;
// 有消息通知是否通过邮箱收取
private Boolean emailNotification;
// 帐号的激活状态
private Boolean active;
话题对象 Topic
private Integer id;
private String title;
private String content;
private Date inTime;
private Date modifyTime;
private Integer userId;
// 评论数
private Integer commentCount;
// 收藏数
private Integer collectCount;
// 浏览数
private Integer view;
// 置顶
private Boolean top;
// 加精
private Boolean good;
// 点赞用户的id英文,隔开的,要计算被多少人点赞过,可以通过英文,分隔这个字符串计算数量
private String upIds;
评论对象 Comment
private Integer id;
private Integer topicId;
private Integer userId;
private String content;
private Date inTime;
private Integer commentId;
// 点赞用户的id
private String upIds;
评论(盖楼)对象 CommentsByTopic
// 话题下面的评论列表单个对象的数据结构
public class CommentsByTopic extends Comment implements Serializable {
private String username;
private String avatar;
// 评论的层级,直接评论话题的,layer即为0,如果回复了评论的,则当前回复的layer为评论对象的layer+1
private Integer layer;
}
通知对象 Notification
private Integer id;
private Integer topicId;
private Integer userId;
// 通知对象ID
private Integer targetUserId;
// 动作: REPLY, COMMENT, COLLECT, TOPIC_UP, COMMENT_UP
private String action;
private Date inTime;
private String content;
// 是否已读
private Boolean read;
授权登录对象 OAuthUser
private Integer id;
// oauth帐号的id
private Integer oauthId;
// 帐号类型,GITHUB, QQ, WECHAT, WEIBO 等
private String type;
// oauth帐号的登录名
private String login;
private String accessToken;
private Date inTime;
// 个人简介
private String bio;
private String email;
// 本地用户的id
private Integer userId;