Nano Hash - криптовалюты, майнинг, программирование

Можно ли усовершенствовать шаблоны scala с помощью play framework 2?

Используя Play Framework 2, я заметил, что отображаемые HTML-шаблоны Scala не любят отступы @if или @for.

Так, например, что-то вроде этого:

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

Будут лишние ненужные места. Чтобы исправить это, мне нужно сделать что-то вроде этого:

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

Что запутается с дополнительными @defining или другими операторами.

Итак, есть ли способ улучшить/украсить рендеринг шаблонов Scala, чтобы избавиться от лишних пробелов?

ОБНОВИТЬ:

Читая эту тему, я заметил лишние пробелы и разрывы строк также добавляются из-за параметров поверх шаблонов. Итак, это:

@(myParam: String)


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

добавит 3 дополнительных разрыва строки поверх результирующего HTML. Что определенно раздражает.

Кажется, в ветке говорится, что на данный момент нет возможности исправить это.


Ответы:


1

Итак, для получения более подробной информации я использовал ответ @biesor и выполнил следующие шаги:

Добавить HtmlCompressor в качестве подключаемого модуля

В Build.scala:

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

Красивый контроллер

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.

08.01.2013
  • Мне это нравится, избегает нарушения DRY, может быть, вы могли бы создать образец приложения для других на Github? 24.01.2013
  • Интересно, можно ли это сделать во время компиляции, поэтому красивая версия - это та, которая встраивается в результирующий класс, вместо того, чтобы приукрашивать ее при каждом запросе. 30.01.2013

  • 2

    Я выпустил плагин Google HTML Compressor для Play 2.1. Вы можете найти его на GitHub.

    29.06.2013
  • Это сработало хорошо для меня, спасибо. Я внес обновление до Play 2.2.1. 18.11.2013
  • Очень отличный плагин. Простая настройка и хорошо работает с фильтром GZIP. 20.09.2014

  • 3

    Конечно, всегда есть какой-то вариант :), обрежьте тело и снова установите заголовок (потому что после операций над строкой он будет возвращен как 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");
    
    04.01.2013
  • интересно, как бы вы сделали это для каждого звонка? изменение каждого запроса для каждого контроллера? 04.01.2013
  • В игре 2.1 есть фильтр (github.com/playframework/Play20/blob/master/framework/src/play/), который будет идеальным решением для этого. Но это очень сложно, вы должны работать с Iteratee API вместо String... Я пробовал несколько дней назад, но это слишком сложно для меня! 04.01.2013
  • @RomainPiel Да, но это проблема? в существующем проекте это вставка из буфера обмена. Сколько у вас есть действий, возвращающих HTML? 20? 30, 5 минут работы. 04.01.2013
  • @RomainPiel Вы можете использовать вспомогательный метод или переопределить Ok. 04.01.2013

  • 4

    Я ожидал ответов, которые действительно «украшают» вывод 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"
    
    14.04.2017

    5

    Вторя ответу bluenote10, я создал следующее, для этого не требуются сторонние библиотеки Dependecies. Было бы неплохо интегрировать его в фильтр, но, к сожалению, сегодня я не знаю, как это правильно сделать.

    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()))
    }
    
    07.09.2017
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..