发表一篇博文
填充管理页面
从主页链接到管理页面时,只简单显示了登陆用户的名称
现在对显示的内容加以丰富
修改Admin中的index()
package controllers;
import java.util.List;
import models.Post;
import models.User;
import play.mvc.Before;
import play.mvc.Controller;
public class Admin extends Controller {
/**
* 首先,用户登陆会被Security拦截,登陆成功会把username放入session中
* session.put("username",username);
* 通过session.contains("username");判断用户是否已经登陆
*
* @Before 访问Admin控制器时,将先执行由该注解标注的方法,进行拦截(过滤/检查)
*/
@Before
static void setConnectedUser() {
//Security.isConnected() 检查session中是否有username为key的map存在
//因为用户登陆后会用username作为key存储登陆信息
if(Security.isConnected()) {
//Security.connected() 取得session中以username为key的value,即用户名
User user = User.find("byUsername", Security.connected()).first();
renderArgs.put("user", user.fullname);
}
}
/**
* 返回管理CRUD功能模块的主页面
* 查询属于当前登陆用户的博文
* 传递到admin/index.html页面进行显示
*/
public static void index(){
String username = Security.connected();
//Post对象的author属性为User类型
List<Post> posts = Post.find("author.username", username).<Post>fetch();
render(posts);
}
}
同样,编辑yabe\app\views\Admin\index.html,对新增内容进行显示
#{extends 'admin.html' /}
<!-- 显示用户及其发布的博文数量 -->
<h3>
Welcome ${user},
<span>
you have written
${posts.size() ?: 'no'}
${posts.pluralize('post','posts')}
so far!
</span>
<!-- posts.pluralizer(x,y) : posts的size为单数,则返回x,否则返回y-->
</h3>
<!-- 循环posts,分别显示每个博文 -->
#{list items:posts, as:'post'}
<p class="post ${post_parity}">
<a href="#">${post.title}</a>
</p>
#{/list}
<!-- 创建新的博文 -->
<p id="newPost">
<a href="#"><span>+</span>write a new post</a>
</p>
进入管理页面http://localhost:9000/admin/index
显示了当前博主发布博文情况,以及发布新博文的按钮
发表一篇博文
三步:
创建Controller,或在Controller中加入action
给action配置路由
编写action对应的模板
在Admin中编写action,一个用于返回一个form表单;一个用于接收form提交的参数
/**
* 返回form的页面
*/
public static void form() {
render();
}
/**
* 接收form提交的数据并处理
*/
public static void save(String title, String content) {
//current login user
User author = User.find("byUsername", Security.connected()).first();
//new post
Post post = new Post(title, content, author);
//Validate
validation.valid(post);
if(validation.hasErrors()) {
//一种简写,等效于 render("Admin/form.html",post);
render("@form",post);
}
//Save object
post.save();
index();
}
配置路由
#form
#open a form page use get method
GET /admin/new Admin.form
#submit form use post method
POST /admin/new Admin.save
编写模板-form表单
#{extends 'admin.html' /}
<h3>Write,<span>a new post</span></h3>
#{form @save()}
#{ifErrors}
<p class="error">
Please correct these errors.
</p>
#{/ifErrors}
<p>
#{field 'title'}
<label>Post title:</label>
<input type="text" name="${field.name}" value="${post?.title}" />
<span class="error">#{error 'post.title' /}</span>
#{/field}
</p>
<p>
#{field 'content'}
<label>Write here:</label>
<textarea name="${field.name}">${post?.content}</textarea>
<span class="error">#{error 'post.content' /}</span>
#{/field}
</p>
<p>
<input type="submit" value="Publish this post to the blog" />
</p>
#{/form}
刷新页面,点击创建一个新的博文
修改admin/index.html,为每个博文设置链接
注意:这里需要传入博文的id,以便后台查询出该博文的所有信息,再返回Post对象给页面进行显示
<!-- 循环posts,分别显示每个博文 -->
#{list items:posts, as:'post'}
<p class="post ${post_parity}">
<a href="@{Admin.form(post.id)}">${post.title}</a>
</p>
#{/list}
修改Admin控制器中的form(),接收id参数
如果id != null ,表示数据库中已经存在此博文,可以查询出来
用于页面的回显
/**
* 返回form的页面
* 初次创建博文,id为空,不返回对象
* id不为空,则查询出对象,传递到页面用作数据回显
*/
public static void form(Long id) {
if(id!=null) {
Post post = Post.findById(id);
render(post);
}
render();
}
修改路由,定制更好看的URL
http://localhost:9000/admin/new?id=6
增加路由
#open a form page use get method
GET /admin/myPosts/{id} Admin.form
GET /admin/new Admin.form
第1条路由:如果一个id参数被提交,将使用第1条路由模式显示URL=== myPosts/6
第2条路由:如果没有id参数被提交,则使用旧的模式显示URL=== new?id=6
之后,URL变为了这种格式:http://localhost:9000/admin/myPosts/6
区分创建与编辑
现在还存在一个问题,新建博文没有问题了
但是,编辑已经存在的博文,保存之后系统会自动将其作为一个新的博文进行发布,而不是更新
因此,需要在form()中加入判断逻辑:
如果已经存在id了,则更新;否则作为新的博文进行保存!
修改Admin控制器的save(),处理创建与编辑两种情况
/**
* 接收form提交的数据并处理
* 增加id参数,由页面传递过来
* 通过id参数是否为空,判断是新建保存还是编辑保存
*/
public static void save(Long id, String title, String content) {
Post post = null;
if(id==null) {
//创建
User author = User.find("username", controllers.Secure.Security.connected()).first();
post = new Post(title, content, author);
} else {
//更新---取出已有对象,更新其内部属性并同步到数据库
post = Post.findById(id);
post.title = title;
post.content = content;
}
//Validate
validation.valid(post);
if(validation.hasErrors()) {
//一种简写,等效于 render("Admin/form.html",post);
render("@form",post);
}
//Save object
post.save();
index();
}
修改form.html模板,加入创建与编辑的不同显示,同时增加id参数的传递
以便后台判断是新建还是编辑已有博文
#{extends 'admin.html' /}
<!--
判断post对象id是否为空
id==null,则新建博文
id!=null,则编辑博文
-->
#{ifnot post?:id}
<h3>Write,<span>a new post</span></h3>
#{/if}
#{else}
<h3>Edit,<span>this post</span></h3>
#{/else}
<!-- 把id传到 Admin控制器的save action中 -->
#{form @save(post?.id)}
#{ifErrors}
<p class="error">
Please correct these errors.
</p>
#{/ifErrors}
<p>
#{field 'title'}
<label>Post title:</label>
<input type="text" name="${field.name}" value="${post?.title}" />
<span class="error">#{error 'post.title' /}</span>
#{/field}
</p>
<p>
#{field 'content'}
<label>Write here:</label>
<textarea name="${field.name}">${post?.content}</textarea>
<span class="error">#{error 'post.content' /}</span>
#{/field}
</p>
<p>
<input type="submit" value="Publish this post to the blog" />
</p>
#{/form}
点击创建一个新的博文
点击一个已存在的博文
同样,将编辑博文的URL路径显示风格进行改变
修改routes文件
带id参数提交时的将使用第1条路由,不带参数则按第2条路由显示URL
#submit form use post method
POST /admin/myPosts/{id} Admin.save
POST /admin/new Admin.save
创建新的博文,保存时的URL使用第1条路由:
http://localhost:9000/admin/myPosts/1 (POST提交)
编辑已存在的博文,保存时的URL使用第2条路由:
http://localhost:9000/admin/new (POST提交)