Skip to content

Commit

Permalink
some scalate refactorings
Browse files Browse the repository at this point in the history
  • Loading branch information
Nathan Hamblen committed Aug 1, 2011
1 parent e43fdbb commit 5acb130
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 43 deletions.
77 changes: 36 additions & 41 deletions scalate/src/main/scala/scalate.scala
@@ -1,49 +1,44 @@

package unfiltered.scalate

import org.fusesource.scalate.{TemplateEngine, Binding, DefaultRenderContext, RenderContext}

import org.fusesource.scalate.{
TemplateEngine, Binding, DefaultRenderContext, RenderContext}
import unfiltered.request.{Path,HttpRequest}
import unfiltered.response.{ResponseWriter}
import unfiltered.request.HttpRequest

import java.io.Writer

/**
* private object that holds the default engine
*/
private[scalate] object ScalateDefaults{
val defaultTemplateDirs = List(new java.io.File("src/main/resources/templates"))
implicit val engine = new TemplateEngine(defaultTemplateDirs)

implicit def renderContext(req: HttpRequest[_], writer: Writer, engine: TemplateEngine) =
new DefaultRenderContext(
unfiltered.util.Optional(req.uri).getOrElse("").split('?')(0),
engine, new java.io.PrintWriter(writer))
}
import java.io.{File,Writer,PrintWriter}

object Scalate {
/* An arity-3 function that constructs an appropriate RenderContext. */
type RenderContextBuilder[A, B] = (HttpRequest[A], Writer, TemplateEngine) => RenderContext
}
/** Constructs a ResponseWriter for Scalate templates.
* Note that any parameter in the second, implicit set
* can be overriden by specifying an implicit value of the
* expected type in a pariticular scope. */
def apply[A, B](request: HttpRequest[A],
template: String,
attributes:(String,Any)*)
( implicit
engine: TemplateEngine = defaultEngine,
contextBuilder: ToRenderContext = defaultRenderContext,
bindings: List[Binding] = Nil,
additionalAttributes: Seq[(String, Any)] = Nil
) = new ResponseWriter {
def write(writer: Writer) {
val scalateTemplate = engine.load(template, bindings)
val printWriter = new PrintWriter(writer)
val context = contextBuilder(Path(request), printWriter, engine)
(attributes ++ additionalAttributes) foreach {
case (k,v) => context.attributes(k) = v
}
engine.layout(scalateTemplate, context)
}
}

/**
* This class will render the given template with the given attributes.
* An implicit Engine and Bindings can be passed to the constructor via
* its alternate parameters set. This is described further in demo-scalate
*/
case class Scalate[A, B](request: HttpRequest[A], template: String, attributes:(String,Any)*)
(
implicit engine: TemplateEngine = ScalateDefaults.engine,
contextBuilder: Scalate.RenderContextBuilder[A, B] = ScalateDefaults.renderContext _,
bindings: List[Binding] = List[Binding](),
additionalAttributes: List[(String, Any)] = List[(String, Any)]()
) extends ResponseWriter {
/* Function to construct a RenderContext. */
type ToRenderContext =
(String, PrintWriter, TemplateEngine) => RenderContext

def write(writer: Writer) {
val scalateTemplate = engine.load(template, bindings)
val context = contextBuilder(request, writer, engine)
for(attr <- additionalAttributes) context.attributes(attr._1) = attr._2
for(attr <- attributes) context.attributes(attr._1) = attr._2
engine.layout(scalateTemplate, context)
}
private val defaultTemplateDirs =
new File("src/main/resources/templates") :: Nil
private val defaultEngine = new TemplateEngine(defaultTemplateDirs)
private val defaultRenderContext: ToRenderContext =
(path, writer, engine) =>
new DefaultRenderContext(path, engine, writer)
}
4 changes: 2 additions & 2 deletions scalate/src/test/scala/ScalateSpec.scala
Expand Up @@ -12,7 +12,7 @@ import org.fusesource.scalate.util.FileResourceLoader

// Unfiltered
import unfiltered.request.HttpRequest
import unfiltered.response.HttpResponse
import unfiltered.response.{HttpResponse,ResponseWriter}

class ScalateSpec extends Specification {

Expand All @@ -23,7 +23,7 @@ class ScalateSpec extends Specification {
when(req.uri).thenReturn("")
req
}
def responseString(scalate: Scalate[_,_]) = {
def responseString(scalate: ResponseWriter) = {
val res = mock(classOf[HttpResponse[Nothing]])
val bos = new ByteArrayOutputStream
when(res.getOutputStream).thenReturn(bos)
Expand Down

0 comments on commit 5acb130

Please sign in to comment.