`
schy_hqh
  • 浏览: 558058 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

(四)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">
				&nbsp;|&nbsp;
				${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}

 

刷新页面http://localhost:9000/


抽取相同部分出来,提高代码复用性

新增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">
				&nbsp;|&nbsp;
				${_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;
}

 

  • 大小: 84.5 KB
  • 大小: 90.4 KB
  • 大小: 74.9 KB
  • 大小: 101.9 KB
分享到:
评论
3 楼 jacksondesign 2013-11-26  
有,和YAML的格式有关,不知道有没有什么好的YAML格式的验证工具没有
2 楼 schy_hqh 2013-11-25  
确定你的User类里面有email属性?
生成getter/setter方法了没有啊?
1 楼 jacksondesign 2013-11-25  
Execution exception
RuntimeException occured : Cannot load fixture initial-data.yml: org.hibernate.PropertyAccessException: could not get a field value by reflection getter of models.User.email

In /app/models/Bootstrap.java (around line 20)
16:
public void doJob()
17:
{
18:
if(User.count() == 0)
19:
{
20:
Fixtures.loadModels("initial-data.yml");
21:
}
22:
}
23:
}
这句话会报异常说是没有办法反射 ,不明白为什么

相关推荐

    play framework测试项目

    "yabe"这个文件名可能是项目的简称或别名,具体含义可能需要查看项目源代码才能明确。通常,一个Play项目会包含以下主要目录结构: 1. `app`:包含所有应用程序代码,如控制器、模型、视图和服务。 2. `conf`:存储...

    新建play框架项目.pdf

    在本教程中,我们将深入理解如何使用Play框架创建一个完整的Web项目,以一个博客应用为例,名为Yabe(Yet Another Blog Engine)。 首先,确保你的计算机已经安装了Java 5或更高版本,因为Play框架依赖于Java环境。...

    yabe:另一个博客引擎-Curso Play 1.3.1

    综上所述,"yabe:另一个博客引擎 - Curso Play 1.3.1"涉及到使用Java语言和Play框架开发的一个博客引擎项目。通过学习这个课程或教程,开发者可以了解如何使用Play框架构建Web应用,并可能涉及数据库集成、模板引擎...

    play_入门学习手册

    在CMD中运行`play new yabe`,然后进入项目目录并执行`play run`启动项目。在浏览器输入`http://localhost:9000`,如果看到项目启动成功,说明配置完成。若要将项目转换为Eclipse项目,可以使用`play eclipsify`命令...

    play框架教程前6章

    安装Play框架很简单,从官方下载页面获取最新二进制包并解压。将Play目录添加到PATH环境变量中,这样就可以在命令行直接使用`play`命令。通过运行`play`检查安装是否成功,如果显示帮助信息,说明已安装正确。 创建...

    yabe:另一个博客引擎(Play Framework 1.3.x)

    矢部 另一个博客引擎(Play Framework 1.3.x)

    学习BACnet/IP协议所使用的Yabe和VTS工具

    同时,这两个工具也适用于实际项目中的设备调试和系统集成工作。安装文件"SetupYabe_v1.2.2.exe"是Yabe的安装程序,而"VTS_3.6.7.zip"则是VTS的压缩包,解压后即可运行。 总的来说,熟悉并掌握Yabe和VTS的使用,...

    yabe:另一个后端库

    yabe:另一个后端库

    SetupYabe_v1.1.9.exe

    Currently supports both BACnet IPv4, IPv6 + BACnet MSTP + BACnet PTP + BACnet Ethernet. Basic functions for read, write, read multiple, write multiple, iam, whois, subscribeCOV, notify, WriteFile, ...

    Play框架7版本教程-数据模型的首次迭代.doc

    User类应该位于`/yabe/app/models/User.java`,并使用`@Entity`注解来声明这是一个JPA实体。`@Entity`告诉JPA框架这个类应该被当作数据库表来处理。此外,User类扩展了`play.db.jpa.Model`类,这个类提供了一些辅助...

    Yet Another Bacnet Explorer:Yabe-BACnet设备的图形资源管理器程序-C#代码-开源

    用C#编写的图形化资源管理器程序,用于浏览BACnet设备(在Windows和Linux上运行)。 当前同时支持BACnet IPv4,IPv6 + BACnet MSTP + BACnet PTP + BACnet以太网。 用于读取,写入,读取多个,写入多个,iam,whois...

    yabe_sql:剧本1.3.x教程紧随其后

    "yabe_sql" 可能是一个开源项目或工具的名字,而 "剧本1.3.x教程" 指的是该项目或工具的1.3.x版本的相关教学材料。"紧随其后" 暗示这是一个系列教程中的一个后续部分,可能是对之前版本的更新或者扩展。 【描述分析...

    hal库生成基础代码,然后添BACnet mtsp部分,已经成功和电脑BACnet模拟软件Yabe通讯成功

    软件平台:stm32cubemx keil5 使用hal库生成基础代码,然后添BACnet mtsp部分,已经成功和电脑BACnet模拟软件Yabe通讯成功。 硬件平台:基于正点原子stm32f407探索者开发板硬件。

    yabe-online-mall.github.io

    "矢部网上商城"是一个基于GitHub Pages部署的在线商城项目,其源代码托管在"yabe-online-mall.github.io"的仓库中。这个项目主要利用HTML(HyperText Markup Language)来构建网页结构,展示了如何使用基本的Web技术...

    BACnet设备Socket UDP通信源码

    通过理解和研究这个源码,开发者可以更好地了解如何在实际项目中实现BACnet设备之间的通信,提高楼宇自动化的互操作性和效率。然而,由于BACnet协议的复杂性,初学者可能需要花费一定时间来熟悉其细节。希望这个源码...

    BACnet常用的开发工具,包括点位扫描工具,主站模拟工具以及抓包分析工具

    一些常用的BACnet点位扫描工具包括Yabe,BACnetscan 等。 BACnet主站模拟工具:主站模拟工具用于模拟BACnet主站的功能,以便测试和验证设备的响应和行为。它们允许开发人员发送和接收BACnet命令和数据,并模拟不同的...

    BacNet协议应用软件

    "yetanotherbacnetexplorer-code-282-trunk"可能表示的是YABE项目的某个版本或分支。"code-282"可能是一个版本号,而"trunk"通常指的是主分支,意味着这是项目的主线开发代码。解压这个文件后,开发者将能看到源代码...

    YABE - Yet Another Bookmarks Extension-crx插件

    语言:English 更好的书签popup 功能: 1.左键单击在新选项卡中打开书签。 2.中间单击或“Ctrl”单击单击“在”新建后台“选项卡中打开书签。 3.... 4.... 5.... v1.2.1 - 节点删除后还原滚动位置。 v1.2.0....

Global site tag (gtag.js) - Google Analytics