playframework - twirl - ¿Es posible embellecer plantillas scala usando play framework 2?
play framework scala forms (5)
Uso de Play Framework 2 Me he dado cuenta de que a las plantillas renderizadas de Scala HTML no les gustan las @if
o @for
.
Entonces, por ejemplo, algo así:
<ul>
@for(test <- tests) {
<li>@test.name</li>
}
</ul>
Tendrá espacios extra innecesarios. Para solucionarlo, necesito hacer algo como eso:
<ul>
@for(test <- tests) {
<li>@test.name</li>
}
</ul>
Que se @defining
con @defining
adicional u otras declaraciones.
Entonces, ¿hay alguna manera de embellecer / embellecer la representación de plantillas de Scala para deshacerse de los espacios en blanco adicionales?
ACTUALIZAR:
Al leer este hilo , he notado que se agregan espacios y saltos de línea adicionales debido a los parámetros en la parte superior de las plantillas. Así que esto:
@(myParam: String)
<!DOCTYPE html>
<html>
<head></head>
<body></body>
</html>
agregará 3 saltos de línea adicionales sobre el HTML resultante. Lo cual es definitivamente molesto
El hilo parece decir que no hay opción en este momento para corregir eso.
Entonces, para más detalles, he usado @biesor answer y seguí estos pasos:
Agregue HtmlCompressor como un complemento
En 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;
}
}
Entonces, todos los controladores deberían extender PrettyController
.
Esperaba respuestas que realmente "embellecen" el resultado HTML, en el sentido de sangrar correctamente el resultado además de eliminar líneas en blanco. Sin embargo, HtmlCompressor
solo comprime la salida y no tiene una bonita lógica de impresión.
Se me ocurrió una solución que utiliza HtmlCompressor
para compresión en producción y Jsoup para impresión bonita durante el desarrollo. No me importa llamar a la conversión de prettify
explícitamente, por lo que mi solución se ve así:
// 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))
}
}
En el modo de desarrollo, esto produce un buen formato de HTML.
Los cambios requeridos para build.sbt
son:
libraryDependencies += "org.jsoup" % "jsoup" % "1.10.2"
libraryDependencies += "com.googlecode.htmlcompressor" % "htmlcompressor" % "1.5.2"
Haciéndome eco de la respuesta de bluenote10, creé lo siguiente, no requiere de dependencias de biblioteca de terceros. Sería bueno integrarlo en un filtro, lamentablemente no estoy seguro de cómo hacerlo correctamente hoy.
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()))
}
Lancé un complemento Google HTML Compressor para Play 2.1. Puedes encontrarlo en GitHub .
Por supuesto, siempre hay alguna opción :), recorte el cuerpo y establezca el encabezado nuevamente (por lo que después de las operaciones en la Cadena se devolverá como text/plain
):
// instead of
return ok(index.render("some"));
// use
return ok(index.render("some").body().trim()).as("text/html; charset=utf-8");
para bucles de "belleza" o si necesita escribir un código más compacto
// instead of
@for(test <- tests) {
<li>@test.name</li>
}
// use
@for(test <- tests) {<li>@test.name</li>}
Y finalmente puedes usar algún compresor (es decir, com.googlecode.htmlcompressor ) para ... minimizar toda la página (en esta muestra solo para el modo de producción)
String output = index.render("some").body().trim();
if (Play.isProd()) output = compressor.compress(output);
return ok(output).as("text/html; charset=utf-8");