国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

[翻譯]Play框架1.2.7版本教程(6) - 對添加標簽的支持

bitkylin / 938人閱讀

摘要:對添加標簽的支持隨著博客的文章越來越多,找到要找的文章越來越難。如果能夠添加標簽,那就能更好地分類文章了。要在模式下啟動應用,輸入添加新的到類確保它能工作。為了保持高效,我們需要向初始數據集添加標簽測試數據。修改來添加一些標簽數據。

對添加標簽的支持

隨著博客的文章越來越多,找到要找的文章越來越難。如果能夠添加標簽,那就能更好地分類文章了。

Tag模型

我們將給博客的模型們添加新成員。對Tag類的定義是非常簡單的:

package models;
 
import java.util.*;
import javax.persistence.*;
 
import play.db.jpa.*;
 
@Entity
public class Tag extends Model implements Comparable {
 
    public String name;
 
    private Tag(String name) {
        this.name = name;
    }
 
    public String toString() {
        return name;
    }
 
    public int compareTo(Tag otherTag) {
        return name.compareTo(otherTag.name);
    }
}

因為有時想要在需要時才創建標簽,我們寫多一個findOrCreateByName(String name)工廠方法。把它加到Tag類:

public static Tag findOrCreateByName(String name) {
    Tag tag = Tag.find("byName", name).first();
    if(tag == null) {
        tag = new Tag(name);
    }
    return tag;
}
給文章打標簽

現在是時候連接TagPost模型。讓我們給Post類添加相應的關系:

…
@ManyToMany(cascade=CascadeType.PERSIST)
public Set tags;
 
public Post(User author, String title, String content) {
    this.comments = new ArrayList();
    this.tags = new TreeSet();
    this.author = author;
    this.title = title;
    this.content = content;
    this.postedAt = new Date();
}
…

注意我們這里使用TreeSet來保持一個有序的標簽列表。(由于我們之前的compareTo實現,按的是字母順序)

我們將保持該關系為單向關系。

我們將給Post類添加一系列輔助函數。第一個用于給Post打標簽:

…
public Post tagItWith(String name) {
    tags.add(Tag.findOrCreateByName(name));
    return this;
}
…

下一個是根據指定標簽查找所有文章:

…
public static List findTaggedWith(String tag) {
    return Post.find(
        "select distinct p from Post p join p.tags as t where t.name = ?", tag
    ).fetch();
}
…

是時候寫一個新的測試用例了。要在test模式下啟動應用,輸入:

$ play test

添加新的@TestBasicTest類:

@Test
public void testTags() {
    // Create a new user and save it
    User bob = new User("bob@gmail.com", "secret", "Bob").save();
 
    // Create a new post
    Post bobPost = new Post(bob, "My first post", "Hello world").save();
    Post anotherBobPost = new Post(bob, "Hop", "Hello world").save();
 
    // Well
    assertEquals(0, Post.findTaggedWith("Red").size());
 
    // Tag it now
    bobPost.tagItWith("Red").tagItWith("Blue").save();
    anotherBobPost.tagItWith("Red").tagItWith("Green").save();
 
    // Check
    assertEquals(2, Post.findTaggedWith("Red").size());
    assertEquals(1, Post.findTaggedWith("Blue").size());
    assertEquals(1, Post.findTaggedWith("Green").size());
}

確保它能工作。

解決難題

如果你想要根據多個標簽來查找相應的文章,該怎么辦?這個問題比表面看上去要難。

我將直接給你所需的JPQL查詢語句:

…
public static List findTaggedWith(String... tags) {
    return Post.find(
            "select distinct p from Post p join p.tags as t where t.name in (:tags) group by p.id, p.author, p.title, p.content,p.postedAt having count(t.id) = :size"
    ).bind("tags", tags).bind("size", tags.length).fetch();
}
…

代碼的關鍵在于,我們需要使用一個having count語句來從連結產生的視圖中過濾出擁有全部標簽的文章。

注意這里我們不能用Post.find("...", tags, tags.count)語法,因為tags是一個變長參數

你可以在前一個測試中加入更多的檢查來測試它:

…
assertEquals(1, Post.findTaggedWith("Red", "Blue").size());
assertEquals(1, Post.findTaggedWith("Red", "Green").size());
assertEquals(0, Post.findTaggedWith("Red", "Green", "Blue").size());
assertEquals(0, Post.findTaggedWith("Green", "Blue").size());
…
標簽集合

我們最好有一個標簽集合來看看有哪些標簽。讓我們給Tag類添加一個方法來生成標簽集合:

public static List getCloud() {
    List result = Tag.find(
        "select new map(t.name as tag, count(p.id) as pound) from Post p join p.tags as t group by t.name order by t.name"
    ).fetch();
    return result;
}

這里,我們使用Hibernate的一個允許我們從JPA查詢中返回自定義對象的特性。返回的結果是一個Map列表,其中每個Map包括標簽名(鍵)和標簽個數(值)。

在我們前面的測試中加多一個檢查:

…
List cloud = Tag.getCloud();
assertEquals(
    "[{tag=Blue, pound=1}, {tag=Green, pound=1}, {tag=Red, pound=2}]",
    cloud.toString()
);
向博客界面添加標簽

現在我們又多了一個瀏覽文章的方式了。為了保持高效,我們需要向初始數據集添加標簽測試數據。

修改/yabe/conf/initial-data.yml來添加一些標簽數據。比如:

…
Tag(play):
    name:           Play
 
Tag(architecture):
    name:           Architecture
 
Tag(test):
    name:           Test
 
Tag(mvc):
    name:           MVC
…

然后添加它們到文章的聲明中:

…
Post(jeffPost):
    title:          The MVC application
    postedAt:       2009-06-06
    author:         jeff
    tags:
                    - play
                    - architecture
                    - mvc
    content:        >
                    A Play
…

在YAML文件的頂部添加Tags的定義,因為它們會被Post用到。

你需要重啟應用來加載新的初始數據。注意Play甚至會告訴你出現在YAML文件中的問題:

然后修改#{display /}標簽,在全文模式下展示標簽集合。修改/yabe/app/views/tags/display.html

…
#{if _as != "full"}
    
         |  ${_post.comments.size() ?: "no"}
        comment${_post.comments.size().pluralize()}
        #{if _post.comments}
            , latest by ${_post.comments[0].author}
        #{/if}
    
#{/if}
#{elseif _post.tags}
    
#{/elseif}
…

標簽頁面

現在我們可以實現通過標簽瀏覽文章了。在#{display /}標簽,之前,我們留下一個空鏈接;現在終于可以用listTagged action補完它(修改yabe/app/views/tags/display.html):

…
- Tagged
#{list items:post.tags, as:"tag"}
    ${tag}${tag_isLast ? "" : ", "}
#{/list}
…

Application控制器創建action方法:

…
public static void listTagged(String tag) {
    List posts = Post.findTaggedWith(tag);
    render(tag, posts);
}
…

如常,我們創建一個特定的路由來保持URI語義化:

GET     /posts/{tag}                    Application.listTagged

我們遇到一個問題,因為這個路由跟之前的沖突了。這兩個路由將匹配同一個URI:

GET     /posts/{id}                     Application.show
GET     /posts/{tag}                    Application.listTagged

不過,因為我們假設一個id是數值類型,而tag不是,我們可以簡單粗暴地用正則表達式解決問題:

GET     /posts/{<[0-9]+>id}             Application.show
GET     /posts/{tag}                    Application.listTagged

最后,我們需要創建/yabe/app/views/Application/listTagged.html模板,用于新的listTagged action:

#{extends "main.html" /}
#{set title:"Posts tagged with " + tag /}
 
*{********* Title ********* }*
 
#{if posts.size() > 1}
   

There are ${posts.size()} posts tagged "${tag}"

#{/if} #{elseif posts}

There is 1 post tagged "${tag}"

#{/elseif} #{else}

No post tagged "${tag}"

#{/else} *{********* Posts list *********}*
#{list items:posts, as:"post"} #{display post:post, as:"teaser" /} #{/list}

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/64099.html

相關文章

  • [翻譯]Play框架1.2.7版本教程(7) - 通過CRUD來實現一個基本管理面板

    摘要:通過來實現一個基本的管理面板目前,我們還沒法使用博客的來寫新的文章,或修改評論。提供了一個即開即用的模塊,可以快速生成一個基本的管理面板。這是因為默認是以的輸出來得到一個模型對象的表示。在本教程的最后一章,你會學到關于本地化信息的更多東西。 通過CRUD來實現一個基本的管理面板 目前,我們還沒法使用博客的UI來寫新的文章,或修改評論。Play提供了一個即開即用的CRUD模塊,可以快速...

    騫諱護 評論0 收藏0
  • [翻譯]Play框架1.2.7版本教程(12) - 國際化和本地化

    摘要:國際化和本地化完成了博客引擎后,我們來考慮額外的一件事應用的國際化和語言的本地化。國際化和本地化我們將分兩步討論,先是國際化,再是本地化。實際上,兩者是同步進行的你在國際化的同時,往往也是在本地化。 國際化和本地化 完成了博客引擎后,我們來考慮額外的一件事:Web應用的國際化和語言的本地化。雖然我們可以一開始就做這件事,但是最好還是先完成該應用的單一語言版本,然后再添加其他語言的支持...

    hoohack 評論0 收藏0
  • [翻譯]Play框架1.2.7版本教程(10) - 完成應用測試

    摘要:完成應用測試我們已經完成了我們想要創建的博客引擎。當然我們已經完成了測試所有模型層的功能。評估代碼覆蓋率當然我們還沒有完成應用所需的所有測試用例。如你所見,我們遠遠沒有完成對應用的全面測試。 完成應用測試 我們已經完成了我們想要創建的博客引擎。不過這個項目尚未完全結束。為了保證代碼的質量,我們需要添加更多的測試。 當然我們已經完成了測試所有模型層的功能。所以博客引擎的核心功能已經被...

    _Dreams 評論0 收藏0
  • [翻譯]Play框架1.2.7版本教程(1)

    摘要:確保你的文本編輯器已經做了相應的配置。第一個,會自動監測源代碼的改變并在運行時自動重載。檢查下面的一行是否出現在應用日志中使用版本控制系統來追蹤變化當你開發一個項目時,最好使用版本控制系統來存儲你的源代碼。 Play是一個Java Web敏捷開發的框架http://www.playframework.com/documentation/1.2.7/home 之所以要翻譯這個教程,是因...

    solocoder 評論0 收藏0
  • [翻譯]Play框架1.2.7版本教程(4) - 瀏覽和提交評論

    摘要:瀏覽和提交評論博客主頁現在已經完成,接下來要完成博客正文頁面。整個頁面將展示當前文章的所有評論,還包括一個用于提交新的評論的表單。刷新瀏覽器,檢查這次是否使用了正確的。給模板添加表單在后面試下提交新的評論。 瀏覽和提交評論 博客主頁現在已經完成,接下來要完成博客正文頁面。整個頁面將展示當前文章的所有評論,還包括一個用于提交新的評論的表單。 創建show action 要顯示文章內...

    AWang 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<