簡介 BLOG首頁已設定完成,緊接著繼續編輯文章細節的頁面。此頁面將呈現文章內所有的評論,並運用form來新增評論。 Creating the ‘show’ action 若要顯示文章詳細頁面,我們需要在Application controller新增一個show()方法: public static void show(Long id) {
Post post = Post.findById(id);
render(post);
} 你會看到這個action非常簡單。我們宣告方法內的參數為id,則就會自動檢索HTTP id參數為Long Java物件。這個參數將被提取出來無論是從查詢句或是URL路徑或是Request本體。 如果我們嚐試送出一個id HTTP參數是不是有效的,該id變數若是null,Play會自動 增加驗證錯誤(validation error)到錯誤容器(rrors container)中。 這個action將顯示在 /yabe/app/views/Application/show.html模板中: #{extends 'main.html' /}
#{set title:post.title /}
#{display post:post, as:'full' /} 先前,我們已準備好display tag,所以,該網頁可以很簡單的編輯 Adding links to the details page 之前display tag中將超連結失效(#符號)。但是現在要將超連結指向Application.show() action。隨著Play你可以很簡單的去超連結模版並運用@{....}符號。這個語法使用路徑並反轉調用URL指定action。讓我們來編輯 /yabe/app/views/tags/display.html tag: ...
<h2 class="post-title">
<a href="@{Application.show(_post.id)}">${_post.title}</a>
</h2>
... 接著重新整理網頁並點選文章標題列超連結,就可以顯示其結果。 但它缺少了回到首頁的超連結。編輯/yabe/app/views/main.html模版來完成標題超連結: ...
<div id="title">
<span class="about">About this blog</span>
<h1><a href="@{Application.index()}">${blogTitle}</a></h1>
<h2>${blogBaseline}</h2>
</div>
... 現在,我們可以在首頁和文章細節頁面之間反覆瀏覽了。 Specifying a better URL 文章細節頁面的URL網址正如你所看見的 --> /application/show?id=1 這是Play採用預設的路徑 --> * /{controller}/{action} {controller}.{action} 我們可以使用更好的方式來為Application.show action自定義URL網址路徑。編輯 /yabe/conf/routes檔案並在第一行上面新增自定義路徑。 GET /posts/{id} Application.show Adding pagination 為了能夠讓使用者瀏覽文件更方便,我們將新增分頁功能。在此將繼續擴充Post class並增加previous 及 next方法: 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 /} tag之前加入原始碼): <ul id="pagination">
#{if post.previous()}
<li id="previous">
<a href="@{Application.show(post.previous().id)}">
${post.previous().title}
</a>
</li>
#{/if}
#{if post.next()}
<li id="next">
<a href="@{Application.show(post.next().id)}">
${post.next().title}
</a>
</li>
#{/if}
</ul> #{display post:post, as:'full' /}
這樣就可以運行成功了!!! Adding the comment form 現在我們須要設定各文章的評論表單。我們需要增加postComment action方式至Application controller之中。 public static void postComment(Long postId, String author, String content) {
Post post = Post.findById(postId);
post.addComment(author, content);
show(postId);
} 正如你所看見我們調用addComment()方法,我們之前新增在Post class之中。接著,來我們來編輯show.html模版的 form表單(加入原始碼在#{display /}之後) #{display post:post, as:'full' /} <h3>Post a comment</h3> #{form @Application.postComment(post.id)} <p> <label for="author">Your name: </label> <input type="text" name="author" id="author" /> </p> <p> <label for="content">Your message: </label> <textarea name="content" id="content"></textarea> </p> <p> <input type="submit" value="Submit your comment" /> </p> #{/form} 現在來試著新增評論,應該是可行。 Adding validation 目前,我們沒有驗證表單機制的功能。我們必須使用這項機制,以確保正確的HTTP參數填寫修改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);
} 別忘了要import play.data.validation.* !!! 正如你所見的,在案件的驗證錯誤,我們必須重新顯示在該文章詳細信息頁面。 我們要修改原始碼的形式顯示錯誤信息: <h3>Post a comment</h3>
#{form @Application.postComment(post.id)}
#{ifErrors}
<p class="error">
All fields are required!
</p>
#{/ifErrors}
<p>
<label for="author">Your name: </label>
<input type="text" name="author" id="author" value="${params.author}" />
</p>
<p>
<label for="content">Your message: </label>
<textarea name="content" id="content">${params.content}</textarea>
</p>
<p>
<input type="submit" value="Submit your comment" />
</p>
#{/form} 注意,我們已經發佈的參數,並再利用以填補至HTML input中。 為了讓使用者UI介面更好,我們將新增一些JavaScript並自動設置,以防發生錯誤。由於該Script使用jQuery及jQuery Tools工具,你必須去額外下載並加入 yabe/public/javascripts/ 資料夾,以及修改main.html模版加入它們: ...
<script src="@{'/public/javascripts/jquery-1.3.2.min.js'}"></script>
<script src="@{'/public/javascripts/jquery.tools.min.js'}"></script>
</head> 現在你可以增加一些Script到show.html模版中(最好寫在底層): <script type="text/javascript" charset="utf-8">
$(function() {
// Expose the form
$('form').click(function() {
$('form').expose({api: true}).load();
});
// If there is an error, focus to form
if($('form .error').size()) {
$('form').expose({api: true, loadSpeed: 0}).load();
$('form input').get(0).focus();
}
});
</script> 這樣評論表單看起來很不錯。我們再繼續增加兩個效果。 首先,我們將顯示成功訊息在成功發表評論之後。為此,我們使用flash scope允許我們使用通過驗證訊息從一個action調用到下一個。此刻,修改postComment action來增加一個成功訊息: 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}
<p class="success">${flash.success}</p>
#{/if}
#{display post:post, as:'full' /}
... 最後,我們將調整postComment action所送出的評論表單設定URL路徑。一如往常,它目前是使用預設的URL路徑,因為目前還沒有自定義任何具體的路徑。所以,就直接新增URL路徑: POST /posts/{postId}/comments Application.postComment |