18

使用Play Framework 2我注意到渲染的Scala HTML模板不喜歡縮進@if@for是否可以使用play framework 2來製作scala模板?

因此,舉例來說,這樣的事情:

<ul> 
    @for(test <- tests) { 
     <li>@test.name</li> 
    } 
</ul> 

會得到額外的不必要的空間。爲了解決這個問題,我需要做這樣的事情:

<ul> 
@for(test <- tests) { 
    <li>@test.name</li> 
} 
</ul> 

這將導致混亂與另外@defining或其他聲明。

那麼,有沒有一種方法來美化Scala模板渲染以擺脫額外的空白空間?

UPDATE:

閱讀this thread我注意到多餘的空格和換行被添加因爲的模板頂部的參數也​​是如此。所以這個:

@(myParam: String) 


<!DOCTYPE html> 
<html> 
    <head></head> 
    <body></body> 
</html> 

將在最終的HTML上添加3個額外的換行符。這絕對是煩人的。

該線程似乎認爲目前沒有選項可以糾正該問題。

回答

16

因此,對於更多的細節我用@biesor答案,並通過這些步驟去:

添加HtmlCompressor作爲一個插件

在Build.scala:

val appDependencies = Seq(
    "com.googlecode.htmlcompressor" % "htmlcompressor" % "1.5.2" 
) 

PrettyController

public class PrettyController extends Controller { 

    public static Results.Status ok(Content content) { 
     return Results.ok(prettify(content)).as("text/html; charset=utf-8");   
    } 

    public static Results.Status badRequest(Content content) { 
     return Results.badRequest(prettify(content)).as("text/html; charset=utf-8");   
    } 

    public static Results.Status notFound(Content content) { 
     return Results.notFound(prettify(content)).as("text/html; charset=utf-8");  
    } 

    public static Results.Status forbidden(Content content) { 
     return Results.forbidden(prettify(content)).as("text/html; charset=utf-8");  
    } 

    public static Results.Status internalServerError(Content content) { 
     return Results.internalServerError(prettify(content)).as("text/html; charset=utf-8");  
    } 

    public static Results.Status unauthorized(Content content) { 
     return Results.unauthorized(prettify(content)).as("text/html; charset=utf-8");  
    } 

    private static String prettify(Content content) { 
     HtmlCompressor compressor = new HtmlCompressor(); 
     String output = content.body().trim(); 

     if (Play.isDev()) { 
      compressor.setPreserveLineBreaks(true); 
     } 

     output = compressor.compress(output); 

     return output; 
    } 
} 

然後每個控制器應擴展PrettyController

+0

我喜歡這個,避免DRY違規,也許你可以在Github上爲其他人創建示例應用程序? – biesior

+3

我不知道這是否可以在編譯時完成,所以漂亮的版本是嵌入到結果類中的版本,而不是在每次請求時都要對其進行優化。 – monzonj

4

當然,總有一些選項:),修剪身體,並重新設置頭左右(原因在字符串操作後,將返回爲text/plain):

// instead of 
return ok(index.render("some")); 

// use 
return ok(index.render("some").body().trim()).as("text/html; charset=utf-8"); 

爲「美」循環或如果您需要編寫更緊湊的代碼

// instead of 
@for(test <- tests) { 
    <li>@test.name</li> 
} 

// use 
@for(test <- tests) {<li>@test.name</li>} 

最後,你可以使用一些壓縮機(即com.googlecode.htmlcompressor),以...縮小整個頁面

(本示例只生產模式)
String output = index.render("some").body().trim(); 
if (Play.isProd()) output = compressor.compress(output); 
return ok(output).as("text/html; charset=utf-8"); 
+0

有趣的是,你會怎麼做每個電話?改變每個控制器的每個請求? –

+0

在2.1中,有一個Filter(https://github.com/playframework/Play20/blob/master/framework/src/play/src/main/scala/play/api/mvc/Filters.scala)機制將是完成此任務的完美解決方案。但它非常複雜,你必須使用Iteratee API而不是String ...我前幾天嘗試過,但對我來說太複雜了! –

+0

@RomainPiel是的,但是這個問題呢?在現有項目中,它是從剪貼板粘貼的。你有多少個返回HTML的動作? 20? 30分鐘,5分鐘的工作。 – biesior

8

我已經爲Play 2.1發佈了Google HTML Compressor插件。你可以在GitHub找到它。

+0

這對我很好,謝謝。我貢獻了升級到Play 2.2.1。 –

+0

非常棒的插件。配置簡單,並可與GZIP過濾器配合使用。 – Gavin

1

我期待的是真正「美化」HTML輸出的答案,除了刪除空白行之外,還可以正確縮進輸出。然而,HtmlCompressor只壓縮輸出,並沒有漂亮的打印邏輯。

我想出了一個解決方案,該解決方案使用HtmlCompressor進行生產壓縮,Jsoup在開發過程中進行漂亮的打印。我不關心顯式調用prettify轉換,所以我的解決辦法是這樣的:

// required extra imports 
import play.twirl.api.Html 
import com.googlecode.htmlcompressor.compressor.HtmlCompressor 
import org.jsoup.Jsoup 
import org.jsoup.parser.Parser 

@Singleton 
class MyController @Inject() (environment: Environment) extends Controller { 

    /** Helper to format Html */ 
    def prettify(content: Html): Html = { 
    val rawString = content.body.trim() 
    val html = environment.mode match { 
     case Mode.Dev => 
     val doc = Jsoup.parse(rawString, "", Parser.xmlParser()) 
     doc.outputSettings().indentAmount(2) 
     Html(doc.toString()) 
     case _ => 
     val compressor = new HtmlCompressor() 
     compressor.setPreserveLineBreaks(true) 
     Html(compressor.compress(rawString)) 
    } 
    html 
    } 

    /** example usage */ 
    def index = Action { 
    Ok(prettify(views.html.index)) 
    } 

} 

在開發模式下,該產生一些很好的格式化的HTML。

build.sbt所需的變化是:

libraryDependencies += "org.jsoup" % "jsoup" % "1.10.2" 
libraryDependencies += "com.googlecode.htmlcompressor" % "htmlcompressor" % "1.5.2" 
0

回顯bluenote10的答案,我創建了以下,它不需要第三方libraryDependecies。將它集成到一個過濾器是很好的,不幸的是我不知道今天如何正確地做到這一點。

import play.twirl.api.Html 

/** Helper to format Html */ 
def prettify(content: Html): Html = { 
    Html(content.body.trim().replaceAll("\\n\\s*\\n", "\n")) 
} 

def index = Action { implicit request => 
    Ok(prettify(views.html.index())) 
} 
相關問題