Is it possible to prettify scala templates using play framework 2?

后端 未结 5 2066
半阙折子戏
半阙折子戏 2021-01-31 20:10

Using Play Framework 2 I\'ve noticed the rendered Scala HTML templates don\'t like indented @if or @for.

So, for example, something like that:<

相关标签:
5条回答
  • 2021-01-31 20:19

    So for more details I've used @biesor answer and went through these steps:

    Add HtmlCompressor as a 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;
        }
    }
    

    Then every controllers should extend PrettyController.

    0 讨论(0)
  • 2021-01-31 20:21

    I've released a Google HTML Compressor plugin for Play 2.1. You can find it on GitHub.

    0 讨论(0)
  • 2021-01-31 20:30

    Echoing on bluenote10's answer I created the following, it does not require third party libraryDependecies. It would be nice to integrate it into a filter, unfortunately I am not sure how to do that correctly today.

    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()))
    }
    
    0 讨论(0)
  • 2021-01-31 20:36

    Of course there is always some option :), trim the body and set header again so (cause after operations on the String it will be returned as text/plain):

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

    for 'beauty' loops or if's you need to write more compact code

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

    And finally you can use some compressor (ie. com.googlecode.htmlcompressor) to... minify whole page (in this sample for production mode only)

    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)
  • 2021-01-31 20:38

    I was expecting answers which truly "prettify" the HTML output, in the sense of properly indenting the output in addition to removing blank lines. However, HtmlCompressor only compresses the output, and has no pretty printing logic.

    I came up with a solution that uses both HtmlCompressor for compression in production, and Jsoup for pretty-printing during development. I don't care about calling the prettify conversion explicitly, so my solution looks like this:

    // 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 mode this produces some nicely formatted HTML.

    The required changes to build.sbt are:

    libraryDependencies += "org.jsoup" % "jsoup" % "1.10.2"
    libraryDependencies += "com.googlecode.htmlcompressor" % "htmlcompressor" % "1.5.2"
    
    0 讨论(0)
提交回复
热议问题