Skip to content

Surprising behavior with Appendable subclasses. #84

Open
@pauldraper

Description

This is a custom format that escapes | as bar.

src/main/scala/example/Example.scala

package example

import play.twirl.api._
import scala.collection.immutable

sealed trait Example extends Appendable[Example] {
  val contentType = "text/example"

  def appendTo(sb: StringBuilder)

  override def toString = {
    val sb = new StringBuilder
    appendTo(sb)
    sb.toString
  }
}

object ExampleFormat extends Format[Example] {
  val empty = raw("")

  def escape(text: String) = raw(text.replace("|", "bar"))

  def fill(elements: immutable.Seq[Example]) = new Example {
    def appendTo(sb: StringBuilder): Unit = elements.foreach(_.appendTo(sb))
  }

  def raw(text: String) = new Example {
    def appendTo(sb: StringBuilder): Unit = sb ++= text
  }
}

src/main/twirl/example/my.ex

@(text: String)

| @text |

The result of example.ex.my("bar") is bar bar bar instead of | bar |.

The template text is unexpectedly being escaped. This is because the runtime type is not Example and https://github.com/playframework/twirl/blob/master/api/src/main/scala/play/twirl/api/BaseScalaTemplate.scala#L20.

This could be improved to be T or a subtype, instead of only T.


(More generally, I feel like the runtime type branching in BaseScalaTemplate could be eliminated.)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions