(四)play之yabe项目【页面】
主页面
显示当前发表博客的完整内容,以及历史博客列表
Bootstrap Job
一个play job任务就是一个在没有任何http请求的情况下执行一些特定的方法
应用程序在启动时或间隔一定时间后自动执行某个方法
应用程序启动便执行基础数据的初始化操作:
- import models.User;
- import play.jobs.Job;
- import play.jobs.OnApplicationStart;
- import play.test.Fixtures;
- /**
- * 使用@OnApplicationStart注释Job,告诉Play在应用程序启动时便执行这个任务
- * DEV模式和PROD模式下,任务执行情况不同
- * DEV模式:等到第一个客户端请求才会执行
- * PROD模式:应用程序启动时就执行
- * @author lenovo
- *
- */
- @OnApplicationStart
- public class Bootstrap extends Job {
- public void doJob() {
- //检查用户是否为空
- if(User.count()==0) {
- Fixtures.loadModels("initial-data.yml");
- }
- }
- }
其中,在yabe\conf目录下新建initial-data.yml文件,用来初始化Blog系统的基础数据!
- # Test data
- User(bob):
- email: bob@gmail.com
- password: secret
- fullname: Bob
- isAdmin: true
- User(jeff):
- email: jeff@gmail.com
- password: secret
- fullname: Jeff
- User(paul):
- email: paul@gmail.com
- password: secret
- fullname: Paul
- Post(firstBobPost):
- title: About the model layer
- postedAt: 2009-06-14
- author: bob
- content: >
- The model has a central position in a Play! application. It is the domain-specific
- representation of the information on which the application operates.
- Martin fowler defines it as :
- Responsible for representing concepts of the business, information about the
- business situation, and business rules. State that reflects the business situation
- is controlled and used here, even though the technical details of storing it are
- delegated to the infrastructure. This layer is the heart of business software.
- Post(secondBobPost):
- title: Just a test of YABE
- postedAt: 2009-03-25
- author: bob
- content: >
- Well, it's just a test.
- Post(jeffPost):
- title: The MVC application
- postedAt: 2009-06-06
- author: jeff
- content: >
- A Play! application follows the MVC architectural pattern as applied to the
- architecture of the Web.
- This pattern splits the application into separate layers: the Presentation
- layer and the Model layer. The Presentation layer is further split into a
- View and a Controller layer.
- Comment(c1):
- author: Guest
- content: >
- You are right !
- postedAt: 2009-06-14
- post: firstBobPost
- Comment(c2):
- author: Mike
- content: >
- I knew that ...
- postedAt: 2009-06-15
- post: firstBobPost
- Comment(c3):
- author: Tom
- content: >
- This post is useless ?
- postedAt: 2009-04-05
- post: secondBobPost
打开yabe\app\controllers\Application.java,修改index()
- package controllers;
- import play.*;
- import play.mvc.*;
- import java.util.*;
- import models.*;
- public class Application extends Controller {
- public static void index() {
- //最新的博客
- Post frontPost = Post.find("order by postedAt desc").first();
- //过去的博客
- List<Post> olderPosts = Post.find("order by postedAt desc").from(1).fetch(10);
- render(frontPost,olderPosts);
- }
- }
修改yabe\app\views\Application\index.html
action通过render()传递对象,在模块中只需要使用${xxx}就能获取到相应的对象,进而展现数据。
- #{extends 'main.html' /}
- #{set title:'Home' /}
- #{if frontPost}
- <div class="post">
- <h2 class="post-title">
- <a href="#">${frontPost.title}</a>
- </h2>
- <div class="post-metadata">
- <span class="post-author">by ${frontPost.author.fullname}</span>
- <span class="post-date">${frontPost.postedAt.format('MMMdd')}</span>
- <span class="post-comments">
- |
- ${frontPost.comments.size() ?: 'no'}
- comment${frontPost.comments.size().pluralize()}
- #{if frontPost.comments}
- , latest by ${frontPost.comments[-1].author}
- #{/if}
- </span>
- </div>
- <div class="post-content">
- ${frontPost.content.nl2br()}
- </div>
- </div>
- #{if olderPosts}
- <div class="older-posts">
- <h3>
- Older posts <span class="from">from this blog</span>
- </h3>
- #{list items:olderPosts, as:'oldPost'}
- <div class="post">
- <h2 class="post-title">
- <a href="#">${oldPost.title}</a>
- </h2>
- <div class="post-metadata">
- <span class="post-author">by ${oldPost.author.fullname}</span>
- <span class="post-date">${oldPost.postedAt.format('dd MMM yy')}</span>
- <div class="post-comments">
- ${oldPost.comments.size() ?: 'no'}
- comment${oldPost.comments.size().pluralize()}
- #{if oldPost.comments}
- - latest by ${oldPost.comments[-1].author}
- #{/if}
- </div>
- </div>
- </div>
- #{/list}
- </div>
- #{/if}
- #{/if}
- #{else}
- <div class="empty">
- There is currently nothing to read here!
- </div>
- #{/else}
抽取相同部分出来,提高代码复用性
新增yabe\app\views\tags\display.html
display.html被index.html使用标签(另一个模板)方式进行操作
由于index.html中通过#{display post:frontPost, as:'home' /}来调用display.html模板
则display.html中就可以通过_post 和 _as 来获取对应的参数值
- #{extends 'main.html' /}
- #{set title:'Home' /}
- <div class="post ${_as == 'teaser' ? 'teaser' : ''}">
- <h2>
- <a href="#">${_post.title}</a>
- </h2>
- <div class="post-metadata">
- <span class="post-author">by ${_post.author.fullname}</span>
- <span class="post-date">${_post.postedAt.format('dd MMM yy')}</span>
- #{if _as!='full'}
- <span class="post-comments">
- |
- ${_post.comments.size() ?: 'no'}
- comment${_post.comments.size().pluralize()}
- #{if _post.comments}
- , latest by ${_post.comments[-1].author}
- #{/if}
- </span>
- #{/if}
- </div>
- #{if _as!='teaser'}
- <div class="post-content">
- <div class="about">Detail:</div>
- ${_post.content.nl2br()}
- </div>
- #{/if}
- </div>
- #{if _as=='full'}
- <div class="comments">
- <h3>
- ${_post.comments.size() ?: 'no'}
- comment${_post.comments.size().pluralize()}
- </h3>
- #{list items:_post.comments, as:'comment'}
- <div class="comment">
- <div class="comment-metadata">
- <span class="comment-author">by ${comment.author},</span>
- <span class="comment-data">${comment.postedAt.format('dd MMM yy')}</span>
- </div>
- <div class="comment-content">
- <div class="about">Detail: </div>
- ${comment.content.escape().nl2br()}
- </div>
- </div>
- #{/list}
- </div>
- #{/if}
修改index.html,直接通过display模板完成页面的显示
- #{extends 'main.html' /}
- #{set title:'Home' /}
- #{if frontPost}
- <!--调用display模板-->
- #{display post:frontPost, as:'home' /}
- #{if olderPosts.size()}
- <div class="older-posts">
- <h3>
- Older posts <span class="form">from this blog</span>
- </h3>
- #{list items:olderPosts ,as:'oldPost'}
- <!--调用display模板-->
- #{display post:oldPost, as:'teaser' /}
- #{/list}
- </div>
- #{/if}
- #{/if}
- #{else}
- <div class="empty">
- There is currently nothing to read here!
- </div>
- #{/else}
刷新页面
修改yabe\public\stylesheets\main.css,对页面进行美观修饰
附:main.css
- /** Main layout **/
- html, body {
- background: #364B66 !important;
- font-family: Helvetica, Arial, Sans !important;
- }
- body {
- width: 900px;
- padding: 0 30px;
- margin: auto;
- }
- /** Blog header **/
- #header {
- padding: 10px 0;
- position: relative;
- }
- #logo {
- display: block;
- height: 49px;
- margin-left: 20px;
- color: #fff;
- font-size: 48px;
- font-weight: bold;
- letter-spacing: -4px;
- text-shadow: 1px 2px 2px #000;
- }
- #logo span {
- color: #f00;
- font-size: 70%;
- }
- #tools {
- list-style: none;
- margin: 0;
- padding: 0;
- position: absolute;
- right: 0;
- top: 30px;
- right: 20px;
- }
- #tools a {
- color: #fff;
- text-decoration: none;
- }
- #title {
- background: #B8C569;
- padding: 20px 30px 30px 20px;
- margin: 20px 0;
- color: #3C4313;
- position: relative;
- -webkit-border-radius: 16px;
- -webkit-box-shadow: 0 2px 0 #93A045;
- -moz-border-radius: 16px;
- }
- /** A little hacky to create arrows without images **/
- .about {
- text-indent: -999em;
- display: block;
- width: 0;
- height: 0;
- border-left: 10px solid transparent;
- border-right: 10px solid transparent;
- border-bottom: 10px solid #BAC36E;
- border-top: 0;
- position: absolute;
- top: -10px;
- left: 60px;
- }
- #title h1 {
- font-size: 64px;
- margin: 0;
- }
- #title h1 a {
- text-decoration: none;
- color: inherit;
- }
- #title h2 {
- font-size: 26px;
- margin: 0;
- font-weight: normal;
- }
- /** Main content **/
- #main {
- background: #314660;
- background: -webkit-gradient(linear, left top, left 30%, from(#314660), to(#364B66));
- -webkit-border-radius: 16px;
- -moz-border-radius: 16px;
- padding: 20px;
- }
- /** Post **/
- .post .post-title {
- margin: 0;
- }
- .post .post-title a {
- font-size: 36px;
- color: #F5C2CC;
- text-decoration: none;
- }
- .post .post-metadata {
- color: #BAC36E;
- display: block;
- font-size: 70%;
- display: inline-block;
- }
- .post .post-author {
- font-size: 130%;
- font-weight: bold;
- }
- .post .post-metadata a {
- color: #9FA85D;
- }
- .post .post-content {
- position: relative;
- background: #fff;
- padding: 10px;
- margin: 10px 0 50px 0;
- -webkit-border-radius: 10px;
- -moz-border-radius: 10px;
- -webkit-box-shadow: 0 2px 0 #BBBBBB;
- }
- .post .about {
- text-indent: -999em;
- display: block;
- width: 0;
- height: 0;
- border-left: 10px solid transparent;
- border-right: 10px solid transparent;
- border-bottom: 10px solid #fff;
- border-top: 0;
- position: absolute;
- top: -6px;
- left: 24px;
- }
- /** Older posts **/
- .older-posts h3 {
- color: #869AB1;
- font-size: 28px;
- margin-bottom: 15px;
- }
- .older-posts h3 .from {
- font-weight: normal;
- font-size: 70%;
- }
- .older-posts .post {
- margin-bottom: 15px;
- border-left: 3px solid #869AB1;
- padding-left: 10px;
- }
- .older-posts .post-title a {
- padding: 0;
- color: #131921;
- font-size: 20px;
- }
- .older-posts .post-metadata {
- color: #869AB1;
- padding: 0;
- font-size: 12px;
- }
- .older-posts .post-metadata a {
- color: #869AB1;
- }
- /** Comments **/
- .comments {
- margin-bottom: 30px;
- }
- h3 {
- color: #869AB1;
- font-size: 18px;
- margin-bottom: 15px;
- }
- h3 span {
- font-size: 80%;
- font-weight: normal;
- }
- .comment {
- width: 70%;
- clear: both;
- }
- .comment .comment-metadata {
- color: #869AB1;
- display: block;
- font-size: 50%;
- display: block;
- float: left;
- width: 80px;
- text-align: right;
- }
- .comment .comment-author {
- font-size: 150%;
- font-weight: bold;
- display: block;
- }
- .comment .comment-content {
- position: relative;
- background: #E4EAFF;
- color: #242C58;
- font-size: 80%;
- margin-top: 10px;
- margin-bottom: 10px;
- margin-left: 100px;
- padding: 10px;
- -webkit-border-radius: 10px;
- -moz-border-radius: 10px;
- }
- .comment .about {
- text-indent: -999em;
- display: block;
- width: 0;
- height: 0;
- border-top: 10px solid transparent;
- border-bottom: 10px solid transparent;
- border-right: 10px solid #E4EAFF;
- border-left: 0;
- position: absolute;
- top: 4px;
- left: -4px;
- }
- /** Form **/
- form {
- padding: 10px;
- background: #253142;
- background: -webkit-gradient(linear, left top, left 60%, from(#253142), to(#364B66));
- -webkit-border-radius: 10px;
- -moz-border-radius: 10px;
- }
- form .error {
- background: #c00;
- color: #fff;
- font-size: 90%;
- padding: 3px 5px;
- -webkit-border-radius: 6px;
- -moz-border-radius: 6px;
- -webkit-box-shadow: 0 2px 0 #800;
- }
- form .error:empty {
- display: none;
- }
- form p {
- margin: 5px 0 0 0;
- }
- form textarea {
- width: 70%;
- height: 150px;
- }
- form input, form textarea {
- font-size: 14px;
- }
- form label {
- display: block;
- font-weight: bold;
- font-size: 90%;
- color: #aaa;
- margin-bottom: 3px;
- }
- #captcha{
- display: block;
- height: 50px;
- }
- .success {
- background: #67AD10;
- color: #fff;
- padding: 10px;
- -webkit-border-radius: 6px;
- -moz-border-radius: 6px;
- -webkit-box-shadow: 0 2px 0 #4E840B;
- }
- /** Pagination **/
- #pagination {
- list-style: none;
- padding: 0;
- position: relative;
- color: #869AB1;
- font-size: 90%;
- top: -20px;
- margin-bottom: 30px;
- }
- #pagination a {
- color: #869AB1;
- font-size: 90%;
- }
- #pagination #previous {
- position: absolute;
- top: 0;
- left: 0;
- }
- #pagination #previous:before {
- content: '<< ';
- }
- #pagination #next {
- position: absolute;
- top: 0;
- right: 0;
- }
- #pagination #next:after {
- content: ' >>';
- }
- /** Footer **/
- #footer {
- border-top: 1px solid #45597A;
- font-size: 70%;
- padding: 10px 30px;
- text-align: center;
- color: #869AB1;
- margin-top: 30px;
- }
- #footer a {
- color: #869AB1;
- font-weight: bold;
- }
- /** Admin **/
- .tags-list .tag {
- cursor: pointer;
- color: red;
- }
- #adminMenu {
- list-style: none;
- padding: 0;
- margin: 0 0 20px 0;
- }
- #adminMenu li {
- display: inline;
- }
- #adminMenu li a {
- color: #fff;
- text-decoration: none;
- font-size: 80%;
- background: #591C64;
- padding: 2px 10px;
- -webkit-border-radius: 9px;
- -moz-border-radius: 9px;
- }
- #adminMenu li.selected a {
- background: #82A346;
- }
- #crudContent {
- color: #8B98AD;
- }
- #crudContent h2 {
- color: #EDC3CD !important;
- }
- #crudContent thead tr {
- background: #512162 !important;
- }
- #crudContent table {
- border: none !important;
- }
- #crudContent table td {
- color: #444;
- }
- tr.odd {
- background: #BECCE7 !important;
- }
- #crud #crudContent, #crudContent form, #crudListSearch, #crudListPagination, .crudButtons {
- background: transparent;
- border: none;
- padding: 0;
- }
- #crudListTable {
- margin: 10px 0;
- }
- .crudField, .objectForm {
- border: none;
- padding-left: 0;
- }
- .crudField label {
- color: #B8FA5C;
- }
- .crudHelp {
- color: #fff !important;
- }
- .crudField .tag {
- color: #111;
- font-size: 80%;
- }
- .crudButtons input {
- font-size: 110%;
- }
- .crudButtons {
- margin-top: 20px;
- border-top: 1px dotted #8B98AD;
- padding-top: 10px;
- }
- .crudFlash {
- border: 0;
- -webkit-border-radius: 8px;
- font-size: 80%;
- padding: 2px 10px;
- }
- .crudField .tag.selected {
- -webkit-border-radius: 8px;
- -moz-border-radius: 8px;
- }
- .crudField .error {
- background: transparent;
- border: none;
- padding: 0;
- color: pink;
- -webkit-box-shadow: none;
- }
- /** Login **/
- #login form {
- background: #8B98AD !important;
- border: 0 !important;
- -webkit-border-radius: 16px;
- -moz-border-radius: 16px;
- }
- #login label, #password-field label, #username-field label {
- color: #161D28 !important;
- font-size: 110% !important;
- }
- #remember-field {
- display: none;
- }
- /** My posts **/
- #admin .post {
- background: #fff;
- padding: 4px;
- margin: 0;
- font-size: 90%;
- }
- #admin .post.odd {
- background: #C0CBE5;
- }
- #admin .post a {
- color: #444;
- }
- #newPost {
- border-top: 1px dotted #C0CBE5;
- padding-top: 15px;
- }
- #newPost a {
- background: #C88116;
- -webkit-border-radius: 12px;
- -moz-border-radius: 12px;
- padding: 5px 10px;
- font-size: 80%;
- text-decoration: none;
- color: #fff;
- font-weight: bold;
- -webkit-box-shadow: 1px 1px 2px rgba(0,0,0,.3);
- }
- #newPost a span {
- background: #7D510E;
- -webkit-border-radius: 8px;
- -moz-border-radius: 8px;
- padding: 0 5px 2px 5px;
- position: relative;
- top: -1px;
- }
- #postContent {
- width: 100%;
- height: 300px;
- }
- .hasError {
- background: pink;
- }
(四)play之yabe项目【页面】的更多相关文章
- (六)play之yabe项目【验证码】
(六)play之yabe项目[验证码] 博客分类: 框架@play framework 添加验证码功能 在Application.java中添加一个action:captcha() /** * 添 ...
- (八)play之yabe项目【身份验证】
(八)play之yabe项目[身份验证] 博客分类: 框架@play framework 添加身份验证 play提供了一个模块-Secure(安全模块),用来做身份验证 允许Secure模块 修改 ...
- (九)play之yabe项目【发表博文】
(九)play之yabe项目[发表博文] 博客分类: 框架@play framework 发表一篇博文 填充管理页面 从主页链接到管理页面时,只简单显示了登陆用户的名称 现在对显示的内容加以丰富 ...
- (七)play之yabe项目【CRUD】
(七)play之yabe项目[CRUD] 博客分类: 框架@play framework 增加CRUD功能 使用CRUD能干嘛?----> 在页面对模型进行增删改查操作,这样有什么实际意义 ...
- 单点登录CAS使用记(四):为登录页面加上验证码
CAS默认的登录页面样式如下,只有用户名与密码两项验证项目. 现在需要为首页登录加上验证码功能. 第一步:首页对默认登录页面的样式进行了调整,使其看上去还算美观. 在页面上加上了验证码项目. 第二步: ...
- (三)play之yabe项目【数据模型】
(三)play之yabe项目[数据模型] 博客分类: 框架@play framework 创建项目 play new yabe What is the application name? [yab ...
- 我是怎么发现并解决项目页面渲染效率问题的(IE调试工具探查器的使用)
#我是怎么发现并解决项目页面渲染效率问题的(IE调试工具探查器的使用) ##背景 之前的项目中,有很多的登记页面,一般都有100-200甚至更加多的字段,而且还涉及到字典.日期及其他效果的显示,载入时 ...
- .NET Core Community 第四个千星项目诞生:微服务框架 Surging
本文所有打赏将全数捐赠于 NCC(NCC 的资金目前由 倾竹大人 负责管理),请注明捐赠于 NCC.捐赠情况将由倾竹大人在此处公示. 提及 .NET 微服务,我们脑海中浮现的一系列印象中,总有 Sur ...
- django之创建第11个项目-页面整合
目的:将如下众多html页面整合到一个index.html页面中. 百度云盘:django之创建第11个项目-页面整合 用下面的方式实现: <!DOCTYPE html> <head ...
随机推荐
- CSS 会被继承的属性
文本 color(颜色,a元素除外) direction(方向) font(字体) font-family(字体系列) font-size(字体大小) font-style(用于设置斜体) font- ...
- cocos2dx 帧动画的两种创建方式
看了好几天cocos2dx的帧动画,现在才有点眉目,为了高效期间我们一般会用到 精灵帧缓存(CCSpriteFrameCache) 和动画缓存(CCAnimationCache) .大体的操作步骤: ...
- 2dtoolkit获取sprite像素大小的方法
获取sprite像素的方法 Vector2 GetPixelSize(tk2dSpriteDefinition def){ ].x; ].y; // Calculate dimensions in p ...
- Outer Join Query Over Dblink Can Fail With ORA-904 (Doc ID 730256.1)
Outer Join Query Over Dblink Can Fail With ORA-904 (Doc ID 730256.1) To Bottom Modified:03-May-2013T ...
- js类(继承)(一)
//call() //调用一个对象的一个方法,以另一个对象替换当前对象. //call([thisObj[,arg1[, arg2[, [,.argN]]]]]) //参数 //thisObj / ...
- ROC和AUC介绍以及如何计算AUC ---好!!!!
from:https://www.douban.com/note/284051363/?type=like 原帖发表在我的博客:http://alexkong.net/2013/06/introduc ...
- MyBatis知多少(12)私有数据库
如果你从事软件开发工作有了一段时间的话,那么肯定听过关于“自己动手还是花钱购买” 的争论.该争论是说,针对一个业务问题,我们是应该自己动手构建自己的解决方案呢,还是应 该花钱购买一个声称已经解决了此问 ...
- C# 解析百度天气数据,Rss解析百度新闻以及根据IP获取所在城市
百度天气 接口地址:http://api.map.baidu.com/telematics/v3/weather?location=上海&output=json&ak=hXWAgbsC ...
- 菜鸟学Windows Phone 8开发(1)——创建第一个应用程序
本系列文章来源MSDN的 面向完全新手的 Windows Phone 8 开发 主要是想通过翻译本系列文章来巩固下基础知识顺带学习下英语和练习下自己的毅力(因为打算每天翻译一篇,但是发现翻译这篇花费了 ...
- ruby -- 基础学习(六)时间计算
计算下一天的这个时刻, # 比如"2013-8-16 18:45:12" 的下一天的这个时刻 “2013-8-17 18:45:12” Time.now + 1.day 如果想得到 ...