Статьи

Интеграция Scalate и Jade с Play 1.2.3

В начале этого года я решил, что хочу изучать Scala . Поскольку я являюсь поклонником веб-фреймворка, я решил, что лучший способ сделать это — изучить лифт . Я внес эти две вещи в свой список задач и оставил их на пару месяцев. После посещения TSSJS 2011 и беседы с Джеймсом Страчаном , я добавил еще пару технологий в свой список обучения. У Джеймса было много интересного о CoffeeScript и Jade, и я решил изучить их.

В мае Devoxx объявил их Call To Papers, и я начал вспоминать о том, насколько крутой была прошлогодняя поездка . Я решил, что попытаюсь получить признание снова, и начал мозговой штурм о разговорах, которые я хотел бы дать. Я придумал «Сравнение веб-фреймворков Scala» и «HTML5 с Play Scala, CoffeeScript и Jade». Причина, по которой я выбрал «Play over Lift» для последнего выступления, заключается в том, что я думаю, что он намного больше соответствует имеющемуся у меня мышлению MVC и простоте изучения веб-фреймворков, которые мне нравятся. Обе темы звучали для меня очень интересно, и я подумал, что они также вдохновят меня на изучение технологий методом грубой силы; где я был ограничен во времени и был бы смущен перед большой аудиторией, если бы мне не удалось.

В середине июля я получил электронное письмо от Стефана с предложением снова выступить на 10-м выпуске Devoxx. Я расплылся в улыбке и быстро понял, что мне нужно многому научиться. Поскольку после летних каникул в Монтане я все еще находился в режиме каникул , я решил подождать, пока не вернусь из Кейп-Код, чтобы начать учебу. Во время моих вторых летних каникул я получил электронное письмо от Devoxx, в котором говорилось, что они хотели бы, чтобы я представил «HTML5 с Play / Scala, CoffeeScript и Jade».

Чтобы изучить все эти технологии, я выбрал подход In Anger — где я буду учиться минимально и учусь в основном на практике. Я заказал CoffeeScript 8 августа, а Программирование на Scala — 2-е издание на следующей неделе (17 августа). Я начал читать обе книги, путешествуя на следующей неделе (я обнаружил, что CoffeeScript и Scala очень похожи, поэтому я не знаю, рекомендую ли я изучать их одновременно). На той же неделе я начал интегрировать Scalate (Jade) в новое приложение Play Scala .

Scalate сообщает на своей домашней странице, что он работает с Play через модуль play-scalate . Они забывают упомянуть, что этот модуль не обновлялся более года или с какой версией Play он работает. Я попытался использовать версию Scateate-0.7.2 и быстро столкнулся с проблемами. Я отправил сообщение в Scalate Google Group, в котором объясняются проблемы компиляции и трассировки стека. Ответ? Сверчки.

Затем я попытался отправить сообщение в группу Google Play и получил гораздо лучший ответ. Вот что они сказали:

Глядя на код модуля Scalate, я не думаю, что он может работать как в Play Scala 0.9.1. Последней версии более 1 года, и мы внесли много изменений в API.

Интеграция Scalate довольно сложна, если вы планируете получить такой же опыт, как и собственный шаблон Play scala, в отношении автоматической перезагрузки и отчетов об ошибках.

Вы можете попробовать перенести модуль на 0.9.1, в основном все, что ему нужно сделать, — это предоставить плагин, который обнаруживает изменения в файле scaml и перекомпилирует их. Никакой специальной интеграции с API Play не требуется.

Узнав, что play-scalate устарел, я связался с владельцем проекта через GitHub и попытался заставить все работать с Play 1.2.3 и Scalate 1.5.1. Я обновил зависимости в проекте, исправил проблемы с компиляцией и попытался собрать. Нет кости:

build: 
    [mkdir] Created dir: /Users/mraible/dev/play-scalate/tmp/classes 
   [scalac] Compiling 7 source files to /Users/mraible/dev/play-scalate/tmp/classes 
   [scalac] error: class file needed by Binding is missing. 
   [scalac] reference type Serializable of package scala refers to nonexisting symbol. 
   [scalac] one error found

Я опубликовал эту ошибку в Play Group и обнаружил, что она вызвана Scalate 1.5.1, требующей Scala 2.9. Я опустился до Scalate 2.4.1 и получил еще одну загадочную ошибку:

build: 
    [mkdir] Created dir: /Users/mraible/dev/play-scalate/tmp/classes 
   [scalac] Compiling 7 source files to /Users/mraible/dev/play-scalate/tmp/classes 
   [scalac] error: class file needed by ScalaController is missing. 
   [scalac] reference value dispatch of package <root> refers to nonexisting symbol. 
   [scalac] one error found

По-видимому, это было вызвано еще одной проблемой версий Scala, и мне предложили гораздо более простое решение для интеграции Scalate. Ниже приведены шаги, которые я выполнил, чтобы интегрировать Scalate 1.4.1 с Play 1.2.3.

  1. Обновлен файл dependencies.yml для ссылок на зависимости Scala и Scalate.
    require:
        - play
        - play -> scala 0.9.1
        - org.fusesource.scalate -> scalate-core 1.4.1:
            transitive: false
        - org.fusesource.scalate -> scalate-util 1.4.1:
            transitive: false
    
  2. Добавлены элементы конфигурации Scalate в application.conf.
    scalate=jade
    jvm.memory=-Xmx256M
    
  3. Создан класс ScalateTemplate, который будет содержать Scalate Engine и отображать шаблон.
    package controllers
    
    import play.Play
    
    object ScalateTemplate {
    
      import org.fusesource.scalate._
      import org.fusesource.scalate.util._
    
      lazy val scalateEngine = {
        val engine = new TemplateEngine
        engine.resourceLoader = new FileResourceLoader(Some(Play.getFile("/app/views")))
        engine.classpath = Play.getFile("/tmp/classes").getAbsolutePath
        engine.workingDirectory = Play.getFile("tmp")
        engine.combinedClassPath = true
        engine.classLoader = Play.classloader
        engine
      }
    
      case class Template(name: String) {
        val scalateType = "." + Play.configuration.get("scalate");
    
        def render(args: (Symbol, Any)*) = {
          scalateEngine.layout(name + scalateType, args.map {
            case (k, v) => k.name -> v
          } toMap)
        }
      }
    
      def apply(template: String) = Template(template)
    }
    
  4. Создана черта Scalate для переопределения метода render () в классе Controller в Play.
    package controllers
    
    import play.mvc.Http
    
    trait Scalate {
    
      def render(args: (Symbol, Any)*) = {
        def defaultTemplate = Http.Request.current().action.replace(".", "/")
        ScalateTemplate(defaultTemplate).render(args: _*);
      }
    }
    
  5. Создан контроллер Application.scala с методом индекса по умолчанию .
    package controllers
    
    import play.mvc._
    import models._
    
    object Application extends Controller with Scalate {
    
      def index = {
        render('user -> User("Raible"))
      }
    }
    

    Класс models / User.scala очень прост:

    package models
    
    case class User(name:String)
    
  6. Наконец, я создал файл index.jade в views / Application.
    -@ var user: models.User
    p Hi #{user.name},
    - for(i <- 1 to 3)
      p= i
    p See, I can count!
    

После того, как все это заработало, я решил, что пришло время запустить его в производство. К счастью, Heroku только что объявила о поддержке Play несколькими днями ранее. Через виноградную лозу я услышал, что Play Scala будет работать, и я попробовал. Это было удивительно легко. Все, что мне нужно было сделать, это создать учетную запись, создать «Procfile» в корневом каталоге моего приложения и запустить команду heroku с последующим нажатием git. Все выглядело великолепно, пока Play не попытался скомпилировать мои шаблоны Jade как шаблоны Groovy:

Cannot start in PROD mode with errors 
Template compilation error (In /app/views/Application/index.jade around line 2) 
The template /app/views/Application/index.jade does not compile : #{user.name} is not closed. 
play.exceptions.TemplateCompilationException: #{user.name} is not closed. 
       at play.templates.TemplateCompiler.generate(TemplateCompiler.java:102) 
       at play.templates.TemplateCompiler.compile(TemplateCompiler.java:15) 
       at play.templates.GroovyTemplateCompiler.compile(GroovyTemplateCompiler.java:4 1)

Решение от Гийома было достаточно просто , и я переименовал мой «Views» каталог для «шаблонов» и обновлен ScalateTemplate.scala соответственно. Вы можете увидеть развернутое приложение на http://play-more.herokuapp.com .

Следующим шагом в моем приключении Play Scala будет попытка заставить работать модуль CoffeeScript . Я также надеюсь интегрировать HTML5 Boilerplate с макетами Jade и Scalate . Я буду делать это с мышлением , что HTML и JavaScript не что Бад. Я многого ожидаю от CoffeeScript и Jade и надеюсь, что получу от них удовольствие так же, как и от Strachan.;-)

А пока вот несколько интересных ссылок, с которыми я недавно встречался и которые обсуждают Scala и / или Play. Я копаю страсть и активность, которая существует в этих сообществах.

От http://raibledesigns.com/rd/entry/integrating_scalate_and_jade_with