<commit_before>package unfiltered.scalate

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

/**
 * 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)
}
 
import unfiltered.response.ResponseWriter
import unfiltered.request.HttpRequest
/**
 * 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(request: HttpRequest[_], template: String, attributes:(String,Any)*)
  (
    implicit engine: TemplateEngine = ScalateDefaults.engine, 
    bindings: List[Binding] = List[Binding](),
    additionalAttributes: List[(String, Any)] = List[(String, Any)]()
  ) extends ResponseWriter{

  import java.io.PrintWriter
  def write(writer: PrintWriter): Unit = {
    import org.fusesource.scalate.DefaultRenderContext
    val scalateTemplate = engine.load(template, bindings)
    val context = new DefaultRenderContext(request.requestURI, engine, writer)
    for(attr <- additionalAttributes) context.attributes(attr._1) = attr._2
    for(attr <- attributes) context.attributes(attr._1) = attr._2 
    scalateTemplate.render(context)
  }
}<commit_msg>type-safe RenderContext construction<commit_after>package unfiltered.scalate

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

import unfiltered.response.{HttpResponse, Responder}
import unfiltered.request.HttpRequest

/**
 * 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[A, B](req: HttpRequest[A], res: HttpResponse[B], engine: TemplateEngine) =
    new DefaultRenderContext(req.requestURI, engine, res.getWriter)
}

object Scalate {
  /* An arity-3 function that constructs an appropriate RenderContext. */
  type RenderContextBuilder[A, B] = (HttpRequest[A], HttpResponse[B], TemplateEngine) => RenderContext
}

/**
 * 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 Responder[B]{
  
  def respond(res: HttpResponse[B]) {
    val writer = res.getWriter()
    try {
      val scalateTemplate = engine.load(template, bindings)
      val context = contextBuilder(request, res, engine)
      for(attr <- additionalAttributes) context.attributes(attr._1) = attr._2
      for(attr <- attributes) context.attributes(attr._1) = attr._2
      scalateTemplate.render(context)
    }
    finally { writer.close() }
  }
}
{'fraction_non_alphanumeric': 0.10376794258373205, 'fraction_numerical': 0.0026913875598086126, 'mean_word_length': 4.941385435168739, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7232069', 'n_tokens_mistral': 937, 'n_tokens_neox': 918, 'n_words': 258}