Twirl Advanced Layout

Based on the following guide: https://www.playframework.com/documentation/2.7.x/ScalaTemplateUseCases

I’d like to know how I can mimic the following Layout with imports:

@(title: String)(sidebar: Html)(content: Html)
<!DOCTYPE html>
<html>
  <head>
    <title>@title</title>
  </head>
  <body>
    <section class="sidebar">@sidebar</section>
    <section class="content">@content</section>
  </body>
</html>
@sidebar = {
  <h1>Sidebar</h1>
}

@main("Home")(sidebar) {
  <h1>Home page</h1>

}

Now let’s say that I want to add a form in the sidebar with my imported custom field constructor which will look like following:

@import helper._

@implicitField = @{
  FieldConstructor(tags.myFieldConstructorTemplate.f)
}

@sidebar = {
  <h1>Sidebar</h1>
	@form(action = routes.HomeController.loginAction()) {
	  @CSRF.formField
	  @inputText(loginForm("username"),
	    '_label -> "",
            '_showConstraints -> false      
          )
      	  @inputText(loginForm("password"),
	    '_label -> "",
            '_showConstraints -> false
	  )
        }

}

@main("Home")(sidebar) {
  <h1>Home page</h1>

}

It doesn’t work, I get the default field constructors. I’d like to first understand why and second know what the work around is.

Please advise,

Thanks

Could you try to move implicitField to be inside of sidecar scope? I would need to check the generated code to understand the scopes better here, but it should fix your problem right now.

Unfortunately it does not work, I get the following error:

Compilation error
identifier expected but ‘def’ found.

@content = {
@implicitField = @{
  @*This is the line with the compilation error*@
  FieldConstructor(tags.myFieldConstructorTemplate.f) 
}

Here is another related issue not sure if I should create another discussion but, I can’t access reverse routing variables in a var.

Here is an example of a reverse routing attempt that returns a string that looks like this in the address bar “http://localhost:9000/@routes.HomeController.index()” instead of a reverse route.

@* request will be required for Play version 2.7*@
@menuList = @{
  import java.util._
  import scala.collection.JavaConverters._

  case class Link (
    displayName: String,
    url: String
  )
  val l1 = Link("Home","@routes.HomeController.index()")
  val l2 = Link("About","@routes.HomeController.about()")

  def links = {
    var list = new java.util.ArrayList[Link]()
    list.add(l1)
    list.add(l2)
    list
  }

  val list = links.asScala
  list
}

<nav class="navbar fixed-top navbar-expand-lg navbar-light bg-light">
  <a class="navbar-brand" href="@routes.HomeController.index()">
    <img src="https://s3-us-west-1.amazonaws.com/570datapublic/example_logo.png" alt="This is the website logo" height="50">
  </a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>

  <div class="collapse navbar-collapse" id="navbarSupportedContent">
    <ul class="navbar-nav mr-auto">
      @for(m <- menuList){
	<li class="nav-item @if( request().path() == m.url){active}">
	  <a class="nav-link" href="@m.url" >@m.displayName</a>
	</li>
     }
    </ul>
      <button class="btn btn-outline-primary my-2 my-sm-0" onclick="location.href='@routes.HomeController.login()';">Login </button>
  </div>
</nav>
<div style="padding-bottom: 10em;"> </div>