Skip to content

Instantly share code, notes, and snippets.

@privateblue
Last active August 29, 2015 14:00
Show Gist options
  • Save privateblue/11403383 to your computer and use it in GitHub Desktop.
Save privateblue/11403383 to your computer and use it in GitHub Desktop.
this is basically pseudo-code
trait SectionData
object Render {
def map(items: (String, Future[SoyValue])*): Seq[(String, Future[SoyValue])] = items
}
implicit class Renderable[T : Renderer[T]](data: T) {
def soy(template: String): Future[SoyValue] = implicitly[Renderer[T]].soy(template, data)
def html(template: String): Future[String] = implicitly[Renderer[T]].html(template, data)
}
object Renderer {
def sequence(items: Seq[(String, Future[SoyValue])]): Future[SoyMap] =
Future.sequence(
items.map {
case (key, fut) => fut.map(key -> _)
}
).map(SoyMap(_))
}
trait Renderer[T <: SectionData] {
implicit def soyToFuture[T](item: T)(implicit sw: SoyWrites[T]) = Future.successful(sw.toSoy(item))
def soy(template: String, data: T): Future[SoyValue] = html(template, data).map(SoyString(_))
def html(template: String, data: T): Future[String] = Renderer.sequence(toMap(template, data)).map(Closure.html(template, _))
def toMap(template: String, data: T): Seq[(String, Future[SoyValue])]
}
case class SidebarData(
val a: String,
val b: List[String]) extends SectionData
object Sidebar {
def apply(authorId: Id): Future[SidebarData] =
for {
a <- ApiClient.getA
b <- ApiClient.getB(authorId)
} yield SidebarData(a, b)
}
implicit object SidebarRenderer extends Renderer[SidebarData] {
def toMap(template: String = "sidebar.soy", data: SidebarData) = Render.map(
"a" -> sd.a,
"b" -> sd.b
)
}
case class PermalinkData(
val sidebar: SidebarData,
val post: Post) extends SectionData
object Permalink {
def apply(postId: Id): Future[PermalinkData] =
for {
post <- ApiClient.getPost(postId)
sidebar <- Sidebar(post.authorId)
} yield PermalinkData(sidebar, post)
}
implicit object PermalinkRenderer extends Renderer[PermalinkData] {
def toMap(template: String = "permalink.soy", data: PermalinkData) = Render.map(
"sidebar" -> pd.sidebar.soy
"post" -> pd.post
)
}
val result: Future[String] = Permalink(postId).map(_.html)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment