37163

Defining and referencing a generic type bound in Play template signature

Question:

I have a number of sorted maps, keyed by a time and with a value of <em>some type</em>. For illustration, consider that I have 3 maps (in Java):

SortedMap<OffsetDateTime, Foo> foo; SortedMap<OffsetDateTime, Boo> bar; SortedMap<OffsetDateTime, Baz> baz;

I wish to write a generic Play template that accepts a map, and a renderer function, and outputs each pair.

<em>Within</em> a template, I can define a <em>local</em> function with the following signature:

@renderTrace[T <: Any](trace: ImmutableSortedMap[OffsetDateTime, Option[T]], renderer: (T) => Html) = {

However, I would like to use this function in multiple templates, so I do not want to define it locally. Rather, I had hoped to define it as its own template (in RenderTrace.scala.html).

Unfortunately, I don't seem be able able to specify the type construction [T <: Any] in the template signature.

How can I define a re-usable, generically typed function?

Answer1:

To flesh out @Ashalynd's suggestion, the template compiler doesn't appear to be smart enough to handle type parameters. Sometimes you can use an underscore as the type parameter (only when you don't care what the type is), but this isn't one of those cases.

A Play (now called twirl) template is essentially just a function that produces result of type play.twirl.api.Html (or play.api.templates.Html for Play 2.2). The templates compiler needs to be worked around, so define a helper package containing your function:

package viewhelpers import play.twirl.api.Html // play.api.templates.Html for 2.2 object ViewExtension { def renderTrace[T <: Any](trace: ImmutableSortedMap[OffsetDateTime, Option[T]], renderer: (T) => Html): Html = ... }

The implementation of renderTrace might not look as nice as it would in the view template, but at least it can work now.

Then in a view:

@(someParams: ....) @import viewhelpers.ViewExtension @{ViewExtension.renderTrace(...)}

Recommend

  • DataTables+RequireJS: Cannot read property 'defaults' of undefined
  • Resizing ToolStripButtons to fit complete BackGround image
  • Linear gradient not applying in Webkit with d3 generated SVG
  • Exposing an enum in a QML signal
  • Rx produce and consume on different threads
  • Deploying pre-encrypted configuration files to a production environment
  • Each Radiobutton for each form or 1 Form for all radiobuttons?
  • What does a hyphen at end of a term mean
  • Calling java project from Mathematica
  • PHP file_exists() anomaly
  • Autohotkey script running program with command line arguments
  • Insertion large number of Entities into SQL Server 2012 [duplicate]
  • What is the difference between a “service account” and an “installed application”?
  • Use sed with regex and (
  • Add reference to ASP.NET 5 Class Library from Framework 4.5 Class Library Project
  • Passing variable arguments using PowerShell's Start-Process cmdlet
  • Clear fused location provider's location for testing
  • Django invalid literal for int() with base 10
  • xtable package: Skipping some rows in the output
  • ADO and msqli connections very slow
  • Limiting recursion to certain level - Duplicate rows
  • PHP buffered output depending on server setting?
  • Sencha Touch 2.0 Controller refs attribute not working?
  • C++ Partial template specialization - design simplification
  • When to use `image` and when to use `Matrix` in Emgu CV?
  • What is the “return” in scheme?
  • Opengl-es onTouchEvents problem or a draw problem? [closed]
  • How to add a column to a Pandas dataframe made of arrays of the n-preceding values of another column
  • script to move all files from one location to another location
  • Which linear programming package should I use for high numbers of constraints and “warm starts” [clo
  • Adding custom controls to a full screen movie
  • Are Kotlin's Float, Int etc optimised to built-in types in the JVM? [duplicate]
  • Running Map reduces the dimensions of the matrices
  • costura.fody for a dll that references another dll
  • Binding checkboxes to object values in AngularJs
  • Observable and ngFor in Angular 2
  • Android Heatmap on canvas or ImageView
  • Net Present Value in Excel for Grouped Recurring CF
  • jQuery Masonry / Isotope and fluid images: Momentary overlap on window resize
  • How to load view controller without button in storyboard?