Skip to content

Commit

Permalink
move value interpretation methods to context
Browse files Browse the repository at this point in the history
  • Loading branch information
timcharper committed Jun 3, 2014
1 parent 60e9990 commit d7d2b65
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 14 deletions.
19 changes: 17 additions & 2 deletions src/main/scala/com/gilt/handlebars/context/Context.scala
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ trait Context[+T] extends Loggable {
val contextFactory: ContextFactory

def asOption: Option[Context[T]] = if (isUndefined || model == null) None else Some(this)

def render: String = if (isUndefined || model == null) "" else model.toString

def notEmpty[A](fallback: Context[A]): Context[A] = if (isUndefined) fallback else this.asInstanceOf[Context[A]]

override def toString = "Context model[%s] parent[%s]".format(model, parent)
Expand Down Expand Up @@ -134,6 +137,20 @@ trait Context[+T] extends Loggable {
}
}

def isCollection = {
model.isInstanceOf[Iterable[_]]
}

def map[R]( mapFn: (Context[T], Option[Int]) => R): Iterable[R] = {
model match {
case l:Iterable[_] => l.zipWithIndex.map {
case (item, idx) => mapFn(contextFactory.createChild(item.asInstanceOf[T], this), Some(idx))
}
case _ =>
Seq(mapFn(this, None))
}
}

protected def invoke(methodName: String, args: List[Any] = Nil): Context[Any] = {
getMethods(model.getClass)
.get(methodName + args.length)
Expand Down Expand Up @@ -166,8 +183,6 @@ trait Context[+T] extends Loggable {
}
}



/**
* Returns a map containing the methods of the class - the reflection calls to generate this map
* have been memoized so this should be performant. The method uses a read-write lock to ensure thread-safe
Expand Down
19 changes: 7 additions & 12 deletions src/main/scala/com/gilt/handlebars/visitor/DefaultVisitor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,13 @@ class DefaultVisitor[T](context: Context[T], partials: Map[String, Handlebars],
callHelper(_, mustache, mustache.params)
}.orElse {
// 2. Check if path exists directly in the context
context.lookup(mustache.path, mustache.params).asOption.map {
_.model.toString
}
context.lookup(mustache.path, mustache.params).asOption.map(_.render)
}.orElse {
// 3. Check if path refers to provided data.
data.get(mustache.path.string).map {
// 3a. Check if path resolved to an IdentifierNode, probably the result of something that looks like
// {{path foo=bar.baz}}. 'bar.baz' in this case was converted to an IdentifierNode
case i:IdentifierNode => context.lookup(i).asOption.map(_.model.toString).getOrElse("")
case i:IdentifierNode => context.lookup(i).render

// 3b. The data was something else, convert it to a string
case other => other.toString
Expand Down Expand Up @@ -104,7 +102,7 @@ class DefaultVisitor[T](context: Context[T], partials: Map[String, Handlebars],

val partialContext = partial.context.map(context.lookup(_)).getOrElse(context)
partials.get(partialName).map {
_(partialContext.model, data, partials, helpers)
_(partialContext.model, data, partials, helpers) // TODO - partial rendering should receive a context; never interact with model directly.
}.getOrElse {
warn("Could not find partial: %s".format(partialName))
""
Expand All @@ -128,15 +126,12 @@ class DefaultVisitor[T](context: Context[T], partials: Map[String, Handlebars],
}
}

// TODO - move to context
protected def renderBlock(ctx: Context[Any], program: Program, inverse: Option[Program]): String = {
if (ctx.truthValue) {
ctx.model match {
case l:Iterable[_] => l.zipWithIndex.map {
case (item, idx) => new DefaultVisitor(contextFactory.createChild(item, ctx), partials, helpers, data + ("index" -> idx)).visit(program)
}.mkString
case model =>
new DefaultVisitor(contextFactory.createChild(model, context), partials, helpers, data).visit(program)
}
ctx.map { (itemContext, idx) =>
new DefaultVisitor(itemContext, partials, helpers, data ++ (idx.map { "index" -> _ })).visit(program)
}.mkString
} else {
inverse.map(visit).getOrElse("")
}
Expand Down

0 comments on commit d7d2b65

Please sign in to comment.