摘要:所以任務(wù)會(huì)在第一個(gè)請(qǐng)求時(shí)同步執(zhí)行。修改來(lái)展示這些對(duì)象你可以閱讀模板是怎么工作的。標(biāo)簽只有兩個(gè)參數(shù)用于展示的文章對(duì)象以及展示的模式可以是全文,全文附評(píng)論,預(yù)告中的一種現(xiàn)在我們可以將冗余代碼替換成標(biāo)簽,重寫主頁(yè)重載頁(yè)面,檢查是否一切安好。
建立第一個(gè)頁(yè)面
既然我們完成了數(shù)據(jù)模型的初步定義,是時(shí)候開(kāi)始創(chuàng)建應(yīng)用的頁(yè)面了。這個(gè)頁(yè)面將僅僅展示最近的博文,以及一個(gè)舊文章的列表。
下面是我們想要實(shí)現(xiàn)的目標(biāo)的草圖:
用默認(rèn)數(shù)據(jù)啟動(dòng)事實(shí)上,在開(kāi)始編寫第一個(gè)頁(yè)面之前,我們還有一件事要做。編寫一個(gè)缺乏數(shù)據(jù)的Web應(yīng)用是乏味的。你甚至不能測(cè)試正在做的事情。但因?yàn)槲覀冞€沒(méi)完成編輯頁(yè)面,所以不能發(fā)布新的文章作為測(cè)試。
有一個(gè)注入默認(rèn)數(shù)據(jù)到博客中的方法是在應(yīng)用加載時(shí)加載一個(gè)fixture文件。要想這么做,我們得創(chuàng)建一個(gè)啟動(dòng)(Bootstrap)任務(wù)。一個(gè)Play任務(wù)可以在任意HTTP請(qǐng)求之外執(zhí)行,比如在應(yīng)用啟動(dòng)時(shí)或者通過(guò)CRON,或在特定時(shí)間點(diǎn)執(zhí)行。
讓我們來(lái)創(chuàng)建/yabe/app/Bootstrap.java任務(wù),通過(guò)Fixtures加載一堆數(shù)據(jù):
import play.*; import play.jobs.*; import play.test.*; import models.*; @OnApplicationStart public class Bootstrap extends Job { public void doJob() { // Check if the database is empty if(User.count() == 0) { Fixtures.loadModels("initial-data.yml"); } } }
我們用@OnApplicationStart注解這個(gè)任務(wù),告訴Play我們希望在應(yīng)用啟動(dòng)時(shí),同步執(zhí)行該任務(wù)。
事實(shí)上該任務(wù)的啟動(dòng)時(shí)機(jī)取決于是在開(kāi)發(fā)模式還是在生產(chǎn)模式。在開(kāi)發(fā)模式,Play會(huì)等待第一個(gè)請(qǐng)求才開(kāi)始。所以任務(wù)會(huì)在第一個(gè)請(qǐng)求時(shí)同步執(zhí)行。這樣,當(dāng)任務(wù)失敗,你將在瀏覽器中看到錯(cuò)誤信息。在生產(chǎn)模式,任務(wù)會(huì)在應(yīng)用啟動(dòng)時(shí)執(zhí)行(就在運(yùn)行play run的時(shí)候),如果出錯(cuò),應(yīng)用將無(wú)法啟動(dòng)。
你可以在yabe/conf/文件夾下創(chuàng)建一個(gè)initial-data.yml。你當(dāng)然可以重用我們之前用過(guò)的data.yml文件。
現(xiàn)在用play run運(yùn)行應(yīng)用,并在瀏覽器打開(kāi)http://localhost:9000/
主頁(yè)面終于,是時(shí)候編寫主頁(yè)了。
你還記得第一個(gè)頁(yè)面是如何輸出的么?首先路由文件指定/URL將調(diào)用controllers.Application.index()action方法。然后這個(gè)方法調(diào)用render()并執(zhí)行/yabe/app/views/Application/index.html模板。
我們將保持這些組件,不過(guò)給它們添加新的代碼來(lái)加載文章列表并展示。
打開(kāi)/yabe/app/views/Application/index.html控制器,修改index()action來(lái)加載文章列表,就像這樣:
package controllers; import java.util.*; import play.*; import play.mvc.*; import models.*; public class Application extends Controller { public static void index() { Post frontPost = Post.find("order by postedAt desc").first(); ListolderPosts = Post.find( "order by postedAt desc" ).from(1).fetch(10); render(frontPost, olderPosts); } }
你可以看懂我們是怎樣向render方法傳遞對(duì)象的嗎?這將允許我們用同樣的名字在模板中訪問(wèn)它們。在這個(gè)例子,變量frontPage和olderPosts將在模板中可用。
修改/yabe/app/views/Application/index.html來(lái)展示這些對(duì)象:
#{extends "main.html" /} #{set title:"Home" /} #{if frontPost}#{if olderPosts}${frontPost.title}
${frontPost.content.nl2br()}#{/if} #{/if} #{else}Older posts from this blog
#{list items:olderPosts, as:"oldPost"} #{/list}There is currently nothing to read here.#{/else}
你可以閱讀模板是怎么工作的。簡(jiǎn)單地說(shuō),它允許你動(dòng)態(tài)訪問(wèn)Java對(duì)象。在幕后我們使用Groovy的語(yǔ)法。大多數(shù)你看到的優(yōu)雅的結(jié)構(gòu)(比如?:運(yùn)算符)就來(lái)自Groovy。但你并不需要為了寫Play模板而學(xué)習(xí)Groovy。如果已經(jīng)熟悉其他像JSP with JSTL的模板語(yǔ)言,你不會(huì)感到惘然無(wú)所適。
Ok,現(xiàn)在刷新博客的首頁(yè)。
不是很美觀,但是至少有內(nèi)容了!
但是因?yàn)樾枰ㄟ^(guò)多種方式展示文章(全文,全文附評(píng)論,預(yù)告),現(xiàn)在我們不得不寫了過(guò)于冗余的代碼。我們應(yīng)該創(chuàng)建一些類似函數(shù)的東西,這樣就可以在不同的模板中調(diào)用它們了。這實(shí)際就是Play標(biāo)簽所做的事情!
要想創(chuàng)建一個(gè)標(biāo)簽,僅需創(chuàng)建新的/yabe/app/views/tags/display.html文件。一個(gè)標(biāo)簽只是另一個(gè)模板。它就像函數(shù)一樣可以接受參數(shù)。#{display /}標(biāo)簽只有兩個(gè)參數(shù):用于展示的文章對(duì)象以及展示的模式(可以是全文,全文附評(píng)論,預(yù)告中的一種)
*{ Display a post in one of these modes: "full", "home" or "teaser" }*#{if _as == "full"}${_post.title}
#{if _as != "teaser"}#{/if}Detail:${_post.content.nl2br()}#{/if}${_post.comments.size() ?: "no"} comment${_post.comments.size().pluralize()}
#{list items:_post.comments, as:"comment"}#{/list}Detail:${comment.content.escape().nl2br()}
現(xiàn)在我們可以將冗余代碼替換成標(biāo)簽,重寫主頁(yè):
#{extends "main.html" /} #{set title:"Home" /} #{if frontPost} #{display post:frontPost, as:"home" /} #{if olderPosts.size()}#{/if} #{/if} #{else}Older posts from this blog
#{list items:olderPosts, as:"oldPost"} #{display post:oldPost, as:"teaser" /} #{/list}There is currently nothing to read here.#{/else}
重載頁(yè)面,檢查是否一切安好。
改進(jìn)布局如你所見(jiàn),index.html繼承自main.html。因?yàn)槲覀冃枰o所有的博客頁(yè)面提供通用的布局,包括博客標(biāo)題和驗(yàn)證鏈接,我們需要修改這個(gè)文件。
編輯/yabe/app/views/main.html:
#{get "title" /} #{doLayout /}
刷新并檢查結(jié)果。大體上能工作,除了blogTitle和blogBaseLine變量未能顯示。這是因?yàn)槲覀冞€沒(méi)把它們傳遞給render(...)調(diào)用。當(dāng)然我們可以在index action的render()調(diào)用中加入它們。但因?yàn)?b>main.html將被作為整個(gè)應(yīng)用的主模板,我們不想每次都添加它們。
要讓一個(gè)控制器(或者其子類)的每個(gè)action都執(zhí)行同樣的代碼,有一個(gè)方式是定義@Before攔截器。
讓我們給Application控制器添加addDefaults()方法:
@Before static void addDefaults() { renderArgs.put("blogTitle", Play.configuration.getProperty("blog.title")); renderArgs.put("blogBaseline", Play.configuration.getProperty("blog.baseline")); }
你需要在Application.java中導(dǎo)入play.Play。
所有添加進(jìn)renderArgs作用域的變量將可被模板訪問(wèn)。并且你可以看到這個(gè)方法從Play.configuration對(duì)象中讀取變量的值。Play.configuration對(duì)象包括/yabe/conf/application.conf的所有配置鍵。
在配置文件中添加這兩個(gè)鍵:
# Blog engine configuration # ~~~~~ blog.title=Yet another blog blog.baseline=We will write about nothing
刷新主頁(yè),檢查現(xiàn)在能否正常展示。
加入樣式現(xiàn)在博客的主頁(yè)已經(jīng)基本完成,但不是很美觀。我們需要添加一些樣式來(lái)裝扮它。如你所見(jiàn),主模板main.html文件引入了/public/stylesheets/main.css。我們將往它里面添加更多樣式。
從這里下載一份樣式表,然后復(fù)制到/public/stylesheets/main.css。(譯者注:最困難的部分就這樣一筆帶過(guò)了,這讓我想到了如何畫一匹馬)
刷新頁(yè)面,你應(yīng)該看到最終的完成稿了。
提交你的成果博客主頁(yè)已經(jīng)完成。又到了提交修改的時(shí)候了:
$ bzr st $ bzr add $ bzr commit -m "Home page"
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/64102.html
摘要:確保你的文本編輯器已經(jīng)做了相應(yīng)的配置。第一個(gè),會(huì)自動(dòng)監(jiān)測(cè)源代碼的改變并在運(yùn)行時(shí)自動(dòng)重載。檢查下面的一行是否出現(xiàn)在應(yīng)用日志中使用版本控制系統(tǒng)來(lái)追蹤變化當(dāng)你開(kāi)發(fā)一個(gè)項(xiàng)目時(shí),最好使用版本控制系統(tǒng)來(lái)存儲(chǔ)你的源代碼。 Play是一個(gè)Java Web敏捷開(kāi)發(fā)的框架http://www.playframework.com/documentation/1.2.7/home 之所以要翻譯這個(gè)教程,是因...
摘要:設(shè)置驗(yàn)證碼任何人都可以在我們的博客下發(fā)布評(píng)論,所以我們需要避免非人類用戶來(lái)擾亂秩序。一個(gè)簡(jiǎn)單的防范方法是設(shè)置驗(yàn)證碼。然后我們修改表單來(lái)顯示驗(yàn)證碼,并把寫入隱藏的域里面。檢查驗(yàn)證碼功能是否完成了。 設(shè)置驗(yàn)證碼 任何人都可以在我們的博客下發(fā)布評(píng)論,所以我們需要避免非人類用戶來(lái)擾亂秩序。一個(gè)簡(jiǎn)單的防范方法是設(shè)置驗(yàn)證碼。 生成驗(yàn)證碼 如何利用Play框架來(lái)生成驗(yàn)證碼?簡(jiǎn)單來(lái)說(shuō),我們需要增...
摘要:瀏覽和提交評(píng)論博客主頁(yè)現(xiàn)在已經(jīng)完成,接下來(lái)要完成博客正文頁(yè)面。整個(gè)頁(yè)面將展示當(dāng)前文章的所有評(píng)論,還包括一個(gè)用于提交新的評(píng)論的表單。刷新瀏覽器,檢查這次是否使用了正確的。給模板添加表單在后面試下提交新的評(píng)論。 瀏覽和提交評(píng)論 博客主頁(yè)現(xiàn)在已經(jīng)完成,接下來(lái)要完成博客正文頁(yè)面。整個(gè)頁(yè)面將展示當(dāng)前文章的所有評(píng)論,還包括一個(gè)用于提交新的評(píng)論的表單。 創(chuàng)建show action 要顯示文章內(nèi)...
摘要:完成應(yīng)用測(cè)試我們已經(jīng)完成了我們想要?jiǎng)?chuàng)建的博客引擎。當(dāng)然我們已經(jīng)完成了測(cè)試所有模型層的功能。評(píng)估代碼覆蓋率當(dāng)然我們還沒(méi)有完成應(yīng)用所需的所有測(cè)試用例。如你所見(jiàn),我們遠(yuǎn)遠(yuǎn)沒(méi)有完成對(duì)應(yīng)用的全面測(cè)試。 完成應(yīng)用測(cè)試 我們已經(jīng)完成了我們想要?jiǎng)?chuàng)建的博客引擎。不過(guò)這個(gè)項(xiàng)目尚未完全結(jié)束。為了保證代碼的質(zhì)量,我們需要添加更多的測(cè)試。 當(dāng)然我們已經(jīng)完成了測(cè)試所有模型層的功能。所以博客引擎的核心功能已經(jīng)被...
摘要:自定義編輯區(qū)域在前一章,我們給創(chuàng)建了一個(gè)關(guān)于面板,并準(zhǔn)備了我的文章的部分。從文章列表開(kāi)始我們僅需要查詢用戶相關(guān)的文章并顯示出來(lái)。如果發(fā)生錯(cuò)誤,它會(huì)刷新表單,顯示錯(cuò)誤信息。它表示使用的默認(rèn)模板。這意味著,如果提交了參數(shù),將選擇這條路由。 自定義編輯區(qū)域 在前一章,我們給yabe創(chuàng)建了一個(gè)關(guān)于面板,并準(zhǔn)備了我的文章的部分。每個(gè)作者可以在這個(gè)部分看到他們發(fā)布過(guò)的文章,以及進(jìn)行編輯或者創(chuàng)建新...
閱讀 2325·2023-04-26 00:38
閱讀 2077·2021-09-07 10:17
閱讀 1050·2021-09-02 15:41
閱讀 774·2021-08-30 09:45
閱讀 629·2019-08-29 17:25
閱讀 3350·2019-08-29 15:07
閱讀 2281·2019-08-29 12:52
閱讀 3824·2019-08-26 13:35