资讯专栏INFORMATION COLUMN

[翻译]Play框架1.2.7版本教程(4) - 浏览和提交评论

AWang / 760人阅读

摘要:浏览和提交评论博客主页现在已经完成,接下来要完成博客正文页面。整个页面将展示当前文章的所有评论,还包括一个用于提交新的评论的表单。刷新浏览器,检查这次是否使用了正确的。给模板添加表单在后面试下提交新的评论。

浏览和提交评论

博客主页现在已经完成,接下来要完成博客正文页面。整个页面将展示当前文章的所有评论,还包括一个用于提交新的评论的表单。

创建"show" action

要显示文章内容,我们需要在Application控制器添加新的action。就叫它show()

public static void show(Long id) {
    Post post = Post.findById(id);
    render(post);
}

如你所见,整个action简明扼要。我们接受一个id参数作为Long类型Java对象。而这个参数可以来自于URL路径或HTTP请求正文。

  

如果接收到的id参数不是有效的数字,id的值会是null,而Play会在errors容器中新增一个验证错误。

这个action会显示/yabe/app/views/Application/show.html模板:

#{extends "main.html" /}
#{set title:post.title /}

#{display post:post, as:"full" /}

因为之前写好了display标签,写这个页面就变得简单。

给正文页面添加链接

在display标签中,我们让所有的链接保持为空(使用#)。是时候让这些链接指向Application.show action。在Play模板中,你可以简单地用@{...}记号来创建链接。这个语法使用路由来“转换”URL成对应的action。

修改/yabe/app/views/tags/display.html标签:

${_post.title}

现在刷新主页,点击一个标题来展示正文。

呃……好像缺了个返回主页面的链接。修改/yabe/app/views/main.html模板来完成标题链接:

About this blog

${blogTitle}

${blogBaseline}

现在终于可以在主页和正文之间切换了。

指定一个更语义化的URL

如你所见,正文页面的URL是:

/application/show?id=1

这是因为Play的默认路由规则就是这样:

*       /{controller}/{action}                  {controller}.{action}

通过指定Application.show action的路径,我们可以使用更语义化的URL。修改/yabe/conf/routes并在第一个路由下面添加新的路由:

GET     /posts/{id}                             Application.show
  

这里id参数将从URL路径提取。你可以从Route File Syntax中阅读更多关于URI模式的内容。

刷新浏览器,检查这次是否使用了正确的URL。

添加分页

要允许用户在文章间方便地流连忘返,我们需要添加分页机制。我们将拓展Post类来按需获取上一篇和下一篇文章:

public Post previous() {
    return Post.find("postedAt < ? order by postedAt desc", postedAt).first();
}

public Post next() {
    return Post.find("postedAt > ? order by postedAt asc", postedAt).first();
}

这个方法在每次请求时都会被多次调用,所以可以优化它们,不过现在先搁置。同时,在show.html模板顶部(在#{display/}标签前)添加分页链接:


现在是不是更棒了?

添加评论表单

是时候开始完成评论表单。先从在Application控制器中增加postComment action方法开始。

public static void postComment(Long postId, String author, String content) {
    Post post = Post.findById(postId);
    post.addComment(author, content);
    show(postId);
}

如你所见,我们只是重用了之前添加给Post类的addComment()

show.html模板添加HTML表单(在#{display /}后面):

Post a comment

#{form @Application.postComment(post.id)}

#{/form}

试下提交新的评论。它应该能工作。

添加验证

目前我们没有在创建评论之前验证表单内容。我们需要验证表单中包括Comment类构造函数中的每个参数。有了Play的验证机制,添加验证只是小菜一碟。修改postComment action来加入@Required验证注解,并检查有没有错误产生:

public static void postComment(Long postId, @Required String author, @Required String content) {
    Post post = Post.findById(postId);
    if (validation.hasErrors()) {
        render("Application/show.html", post);
    }
    post.addComment(author, content);
    show(postId);
}
  

也不要忘了引入play.data/validation.*

如你所见,如果发生验证错误,我们重新输出正文页面。我们需要修改表单代码来显示错误信息:

Post a comment

#{form @Application.postComment(post.id)} #{ifErrors}

All fields are required!

#{/ifErrors}

#{/form}

注意到我们重用已经提交的参数来填充HTML input元素的值。

为了让博客的用户体验更优,我们将添加一点Javascript来自动聚焦到发生错误的地方。首先,需要JQuery和JQuery Tools Expose,你得把它们引入进来。下载这两个库到yabe/public/javascripts/文件夹,并修改main.html模板来引入它们:


    

  

注意当前版本的Play内置的JQuery要比教程用到的新。

现在你可以在show.html模板底部添加这段代码:


现在评论框看起来真的美极了。我们还有加多两样东西。

首先,我们将在评论成功提交之后显示一个成功信息。为此,我们需要使用flash作用域来允许我们从一个action调用传递信息到下一个action。

修改postComment来添加成功信息:

public static void postComment(Long postId, @Required String author, @Required String content) {
    Post post = Post.findById(postId);
    if(validation.hasErrors()) {
        render("Application/show.html", post);
    }
    post.addComment(author, content);
    flash.success("Thanks for posting %s", author);
    show(postId);
}

并在show.html顶部添加可能显示成功信息的位置:

…
#{if flash.success}
    

${flash.success}

#{/if} #{display post:post, as:"full" /} …

最后我们将修改postComment action所用的URL。因为我们没有给它指定路由,现在它用的是默认的路由。所以在应用的路由文件中添加下面一行:

POST    /posts/{postId}/comments                Application.postComment

终于完成了。记得把改动提交到bazaar。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/64101.html

相关文章

  • [翻译]Play框架1.2.7版本教程(5) - 设置验证码

    摘要:设置验证码任何人都可以在我们的博客下发布评论,所以我们需要避免非人类用户来扰乱秩序。一个简单的防范方法是设置验证码。然后我们修改表单来显示验证码,并把写入隐藏的域里面。检查验证码功能是否完成了。 设置验证码 任何人都可以在我们的博客下发布评论,所以我们需要避免非人类用户来扰乱秩序。一个简单的防范方法是设置验证码。 生成验证码 如何利用Play框架来生成验证码?简单来说,我们需要增...

    姘存按 评论0 收藏0
  • [翻译]Play框架1.2.7版本教程(3) - 建立第一个页面

    摘要:所以任务会在第一个请求时同步执行。修改来展示这些对象你可以阅读模板是怎么工作的。标签只有两个参数用于展示的文章对象以及展示的模式可以是全文,全文附评论,预告中的一种现在我们可以将冗余代码替换成标签,重写主页重载页面,检查是否一切安好。 建立第一个页面 既然我们完成了数据模型的初步定义,是时候开始创建应用的页面了。这个页面将仅仅展示最近的博文,以及一个旧文章的列表。 下面是我们想要实...

    inapt 评论0 收藏0
  • [翻译]Play框架1.2.7版本教程(2) - 数据模型的首次迭代

    摘要:数据模型的首次迭代接下来我们要开始完成我们的博客引擎的模型部分。一个普遍的选择是使用关系型数据库。不要认为生成的成员变量是函数变量,其实它是技术变量。当你在中运行应用时,会自动切换到框架并加载对应的。再次运行测试并检查是否一切安好。 数据模型的首次迭代 接下来我们要开始完成我们的博客引擎的模型部分。 JPA入门 模型层是一个Play应用的核心(对于其他Web框架也同样成立)。它是...

    charles_paul 评论0 收藏0
  • [翻译]Play框架1.2.7版本教程(7) - 通过CRUD来实现一个基本的管理面板

    摘要:通过来实现一个基本的管理面板目前,我们还没法使用博客的来写新的文章,或修改评论。提供了一个即开即用的模块,可以快速生成一个基本的管理面板。这是因为默认是以的输出来得到一个模型对象的表示。在本教程的最后一章,你会学到关于本地化信息的更多东西。 通过CRUD来实现一个基本的管理面板 目前,我们还没法使用博客的UI来写新的文章,或修改评论。Play提供了一个即开即用的CRUD模块,可以快速...

    骞讳护 评论0 收藏0
  • [翻译]Play框架1.2.7版本教程(12) - 国际化本地化

    摘要:国际化和本地化完成了博客引擎后,我们来考虑额外的一件事应用的国际化和语言的本地化。国际化和本地化我们将分两步讨论,先是国际化,再是本地化。实际上,两者是同步进行的你在国际化的同时,往往也是在本地化。 国际化和本地化 完成了博客引擎后,我们来考虑额外的一件事:Web应用的国际化和语言的本地化。虽然我们可以一开始就做这件事,但是最好还是先完成该应用的单一语言版本,然后再添加其他语言的支持...

    hoohack 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<