使用CRUD进行管理

开发至现阶段,我们并没有为博客引擎实现创建文章或审核评论等功能。Play提供的 CRUD模块非常适合原型开发,可以帮助开发者快速生成基本管理域。


12.7.1 开启CRUD模块#

      Play提供了很多实用的模块,可以很方便地集成到应用中。模块的好处是提高了应用中组件的重用性,以及将大的应用拆分成多个小应用进行管理。CRUD模块是Play提供便于原型管理的组件,该模块会检查Model类的内部结构,并自动创建简单的管理列表和表单。

      在/yabe/conf/application.conf文件中进行如下配置,开启CRUD模块:

# Import the crud module
module.crud=${play.path}/modules/crud

      CRUD模块自带了一些通用的路由规则,需要在/yabe/conf/routes文件中进行配置:

# Import CRUD routes
*      /admin              module:crud

      重启应用后CRUD模块生效。当用户以http://localhost:9000/admin访问应用时,框架会自动导入所有CRUD路由规则。


12.7.2 声明CRUD控制器#

      为了使模型对象集成到CRUD管理域中,我们需要为每个模型对象定义继承于controllers.CRUD的控制器。例如在/yabe/app/controllers/目录下创建Posts.java文件,并使之继承于controllers.CRUD,就完成了Post模型的CRUD管理:

package controllers;
 
import play.*;
import play.mvc.*;
 
public class Posts extends CRUD {    
}


注意:

推荐使用模型对象的复数形式为CRUD控制器命名,这样做便于Play自动为每个控制器找到关联的模型对象。如果我们希望使用其他名字命名,可以使用@CRUD.For注解。


      接下来分别为每个模型创建CRUD控制器类:

package controllers;
 
import play.*;
import play.mvc.*;
 
public class Users extends CRUD {    
}

package controllers;
 
import play.*;
import play.mvc.*;
 
public class Comments extends CRUD {    
}

package controllers;
 
import play.*;
import play.mvc.*;
 
public class Tags extends CRUD {    
}

      打开http://localhost:9000/admin/访问管理域,如图12.19所示。

图片资源/guide7-1.png

(图12.19 访问管理域)

      管理域列表中的对象名称很晦涩,不方便管理,这是因为CRUD模块默认使用toString()方法返回模型对象的名称。为所有模型覆盖toString()方法,优化模型对象在管理域中的显示。

      以User类为例,重写toString()方法:

...
public String toString() {
    return email;
}
...


12.7.3 添加验证#

      CRUD模块提供的管理域只是原型产品,不是非常完善,并没有提供任何表单的验证规则。我们只需在定义模型对象时添加验证注解,CRUD模块就能够从注解中获得验证规则,对表单数据进行验证。为User类添加验证注解:

package models;
 
import java.util.*;
import javax.persistence.*;
 
import play.db.jpa.*;
import play.data.validation.*;
 
@Entity
public class User extends Model {
 
    @Email
    @Required
    public String email;
    
    @Required
    public String password;
    
    public String fullname;
    public boolean isAdmin;
    
...

      进入管理域中User对象的编辑或者创建页面,就会发现验证规则已经自动添加到表单中了,如图12.20所示:

图片资源/guide7-2.png

(图12.20 添加验证规则)

      为Post类添加验证注解:

package models;
 
import java.util.*;
import javax.persistence.*;
 
import play.db.jpa.*;
import play.data.validation.*;
 
@Entity
public class Post extends Model {
 
    @Required
    public String title;
    
    @Required
    public Date postedAt;
    
    @Lob
    @Required
    @MaxSize(10000)
    public String content;
    
    @Required
    @ManyToOne
    public User author;
    
    @OneToMany(mappedBy="post", cascade=CascadeType.ALL)
    public List<Comment> comments;
    
    @ManyToMany(cascade=CascadeType.PERSIST)
    public Set<Tag> tags;
        
...

      刷新浏览器,Post编辑界面如图12.21所示:

图片资源/guide7-3.png

(图12.21 添加验证规则)

      细心的读者可能会发现表单中微妙的变化,@MaxSize验证注解改变了Post表单的呈现方式,将content的输入框换成了文本域。

      最后为Comment和Tag类增加验证规则:

package models;
 
import java.util.*;
import javax.persistence.*;
 
import play.db.jpa.*;
import play.data.validation.*;
 
@Entity
public class Tag extends Model implements Comparable<Tag> {
 
    @Required
    public String name;
 
...
package models;
 
import java.util.*;
import javax.persistence.*;
 
import play.db.jpa.*;
import play.data.validation.*;
 
@Entity
public class Comment extends Model {
 
    @Required
    public String author;
    
    @Required
    public Date postedAt;
     
    @Lob
    @Required
    @MaxSize(10000)
    public String content;
    
    @ManyToOne
    @Required
    public Post post;
 
...


12.7.4 使用更友好的表单label#

      CURD模块默认使用模型的属性名作为表单label。因为我们在定义模型属性时经常使用简写,所以管理域的表单label并不是非常直观。我们可以配置/yabe/conf/messages文件,自定义表单label,提供更友好的管理域界面。


提示:

事实上,我们可以为不同的语言提供独立的messages文件,比如将法语的本地化操作配置在/yabe/conf/messages.fr文件中。前面的章节已经介绍如何添加本地化语言。


      将以下表单label配置到messages文件中:

title=Title
content=Content
postedAt=Posted at
author=Author
post=Related post
tags=Tags set
name=Common name
email=Email
password=Password
fullname=Full name
isAdmin=User is admin

      刷新浏览器,就可以看到新的表单label,如图12.22所示:

图片资源/guide7-4.png

(图12.22 更改表单label)


12.7.5 自定义显示评论列表页面#

      CRUD模块具有可定制化的特性。管理域中查看默认文章评论列表页面时,只会显示一列数据,这显然不能满足我们的需求。我们可能会要求增加更多的列,特别是增加“文章关联列”来帮助我们筛选相关的post。

      我们通常采用覆盖CRUD模块的Action或者模板来实现页面定制功能。以定制文章评论列表页面为例:只需在/yabe/app/views/Comments/目录下定义list.html模版,就能覆盖管理域的默认list.html界面。

      CRUD模块引入后为框架提供了一些额外的Play命令。crud:ov命令可以帮助我们覆盖任何模版。在命令行中输入:

play crud:ov --template Comments/list

      就会在/yabe/app/views/Comments/目录下生成list.html文件:

#{extends 'CRUD/layout.html' /}
 
<div id="crudList" class="${type.name}">
        
        <h2 id="crudListTitle">&{'crud.list.title', type.name}</h2>
 
        <div id="crudListSearch">
                #{crud.search /}
        </div>
 
        <div id="crudListTable">
                #{crud.table /}
        </div>
        
        <div id="crudListPagination">
                #{crud.pagination /}
        </div>
        
        <p id="crudListAdd">
                <a href="@{blank()}">&{'crud.add', type.modelName}</a>
        </p>
 
</div>

      #{crud.table/}标签的功能是生成管理域的列表,我们可以修改#{crud.table/}标签的fields参数来增加更多的列:

#{crud.table fields:['content', 'post', 'author'] /}

      这样管理域的列表中就会显示三列属性了,如图12.23所示:图片资源/guide7-5.png

(图12.23 增加更多列的table)

      按照以上方式定义,在使用时可能会出现问题。因为评论中content字段可能会非常长,直接在列表中显示会破坏管理域的页面布局,我们需要将较长的content内容进行截断处理。

      继续修改#{crud.custom/}标签的内容,定义content字段的显示方式:

#{crud.table fields:['content', 'post', 'author']}
 #{crud.custom 'content'}
  <a href="@{Comments.show(object.id)}">
   ${object.content.length() > 50 ? object.content[0..50] + '…' : object.content}
  </a>
 #{/crud.custom}
#{/crud.table}


12.7.6 自定义添加文章页面#

      我们也可以定制添加文章页面。该页面主要由输入表单构成,其中为文章添加标签的操作非常繁琐,我们可以定制更简洁的标签输入功能。使用crud:ov命令覆盖Posts/show模版:

play crud:ov --template Posts/show

      以下代码为生成的/yabe/app/views/Posts/show.html模版内容:

#{extends 'CRUD/layout.html' /}
 
<div id="crudShow" class="${type.name}">
        
<h2 id="crudShowTitle">&{'crud.show.title', type.modelName}</h2>
 
<div class="objectForm">
#{form action:@save(object.id), enctype:'multipart/form-data'}
    #{crud.form /}
    <p class="crudButtons">
        <input type="submit" name="_save" value="&{'crud.save', type.modelName}" />
        <input type="submit" name="_saveAndContinue" value="&{'crud.saveAndContinue', type.modelName}" />
    </p>
#{/form}
</div>
 
#{form @delete(object.id)}
    <p class="crudDelete">
        <input type="submit" value="&{'crud.delete', type.modelName}" />
    </p>
#{/form}
 
</div>

      修改/yabe/app/views/Posts/show.html模版,将#{crud.custom /}标签内嵌至#{crud.form/}标签体中,实现文章标签选择的定制:

#{crud.form}
    #{crud.custom 'tags'}
        <label for="tags">
            &{'tags'}
        </label>
        <style type="text/css">
                .tags-list .tag {
                    cursor: pointer;
                    padding: 1px 4px;
                }
                .tags-list .selected {
                    background: #222;
                    color: #fff;
                }
            </style>
            <script type="text/javascript">
                var toggle = function(tagEl) {
                    var input = document.getElementById('h'+tagEl.id);
                    if(tagEl.className.indexOf('selected') > -1) {
                        tagEl.className = 'tag';
                        input.value = '';
                    } else {
                        tagEl.className = 'tag selected';
                        input.value = tagEl.id;
                    }
                }
            </script>
            <div class="tags-list">
                #{list items:models.Tag.findAll(), as:'tag'}
                   <span id="${tag.id}" onclick="toggle(this)" 
                        class="tag ${object.tags.contains(tag) ? 'selected' : ''}">
                       ${tag}
                   </span> 
                   <input id="h${tag.id}" type="hidden" name="${fieldName}" 
                            value="${object.tags.contains(tag) ? tag.id : ''}" />
                #{/list}
            </div>
    #{/crud.custom}
#{/crud.form}

      在show.html模版的定制中,我们使用JavaScript实现了简单的标签选择器,使页面的用户体验变得更友好,如图12.24所示。

图片资源/guide7-6.png(图12.24 JavaScript实现的标签选择器)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值