18

Mit Play Framework 2 habe ich bemerkt, dass die gerenderten Scala HTML-Templates nicht wie eingerückt @if oder @for eingerahmt sind.Ist es möglich, Scala-Vorlagen mit Play Framework 2 zu verschönern?

So zum Beispiel so etwas wie das:

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

Werden zusätzliche nicht benötigte Räume haben. Um es zu beheben, muß ich, so etwas tun:

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

Welche erhält chaotisch mit zusätzlichen @defining oder anderen Aussagen.

Also, gibt es eine Möglichkeit, Scala Vorlagen Rendering zu verschönern/verschönern, um zusätzliche Leerzeichen zu entfernen?

UPDATE:

Lesen this thread Ich habe zusätzliche Leerzeichen und Zeilenumbrüche bemerkt werden auch hinzugefügt, da der Parameter auf der Vorlagen. Also das:

@(myParam: String) 


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

wird 3 zusätzliche Zeilenumbrüche auf die resultierende HTML hinzufügen. Was definitiv nervig ist.

Der Thread scheint zu sagen, dass es im Moment keine Option gibt, das zu korrigieren.

Antwort

16

Also für mehr Details habe ich @biesor Antwort verwendet und ging durch diese Schritte:

hinzufügen HtmlCompressor als Plugin

In 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; 
    } 
} 

Dann sollten alle Controller PrettyController erweitern.

+0

Ich mag das, vermeidet DRY-Verletzung, vielleicht könnten Sie Beispiel-App für andere auf dem Github erstellen? – biesior

+3

Ich frage mich, ob dies zur Kompilierzeit getan werden könnte, also ist die hübsche Version diejenige, die in die resultierende Klasse eingebettet wird, anstatt sie bei jeder Anfrage zu verschönern. – monzonj

4

Natürlich gibt es immer einige Option :), schneiden wieder den Körper und setzen Header so (Ursache nach Operationen am String wird es als text/plain zurückgegeben werden):

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

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

für ‚Schönheit‘ Schleifen oder wenn Sie Notwendigkeit, kompakter Code

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

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

zu schreiben Und schließlich können Sie einig Kompressor verwenden (dh. com.googlecode.htmlcompressor) zu ... minify ganze Seite (in diesem Beispiel für die Produktion Modus)

String output = index.render("some").body().trim(); 
if (Play.isProd()) output = compressor.compress(output); 
return ok(output).as("text/html; charset=utf-8"); 
+0

interessant, wie würden Sie das für jeden Anruf tun? Ändern Sie jede Anfrage für jeden Controller? –

+0

In Play 2.1 gibt es einen Filter (https://github.com/playframework/Play20/blob/master/framework/src/play/src/main/scala/play/api/mvc/Filters.scala) Mechanismus, der wird die perfekte Lösung sein, dies zu tun. Aber es ist sehr kompliziert, Sie müssen mit der Iteratee API statt String arbeiten ... Ich habe es vor ein paar Tagen versucht, aber zu kompliziert für mich! –

+0

@RomainPiel Ja, aber ist das Problem? In einem bestehenden Projekt wird es aus der Zwischenablage eingefügt. Wie viele HTML-Aktionen hast du? 20? 30, 5 Minuten Arbeit. – biesior

8

Ich habe ein Google HTML Compressor Plugin für Play 2.1 veröffentlicht. Sie finden es unter GitHub.

+0

Das hat gut für mich funktioniert, danke. Ich habe ein Upgrade auf Play 2.2.1 beigesteuert. –

+0

Sehr großes Plugin. Einfache Konfiguration und funktioniert gut mit GZIP-Filter. – Gavin

1

Ich erwartete Antworten, die wirklich die HTML-Ausgabe "verschönern", in dem Sinne, dass die Ausgabe zusätzlich zum Entfernen von Leerzeilen richtig eingerückt wird. HtmlCompressor komprimiert jedoch nur die Ausgabe und hat keine schöne Drucklogik.

Ich kam mit einer Lösung, die sowohl HtmlCompressor für die Komprimierung in der Produktion und Jsoup für Pretty-Druck während der Entwicklung verwendet. Ich kümmere mich nicht um die prettify Umwandlung explizit aufrufen, so meine Lösung sieht wie folgt aus:

// 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)) 
    } 

} 

In dev Modus dies einige schön formatierte HTML erzeugt.

Die erforderlichen Änderungen an build.sbt sind:

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

In Anlehnung an bluenote10 Antwort ich folgendes erstellt, spielt es keine dritte Partei libraryDependecies erfordern. Es wäre schön, es in einen Filter zu integrieren, leider bin ich mir nicht sicher, wie ich das heute richtig machen soll.

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())) 
} 
Verwandte Themen