Originally posted and answered here:
https://groups.google.com/forum/#!topic/play-framework/s-ufMIbLz3c
But when I put:
<div>
@if (request.uri == "/") { "Home Menu Selected" }
</div>
But I got:
'(' expected but ')' found.
Originally posted and answered here:
https://groups.google.com/forum/#!topic/play-framework/s-ufMIbLz3c
But when I put:
<div>
@if (request.uri == "/") { "Home Menu Selected" }
</div>
But I got:
'(' expected but ')' found.
Assuming you have the request object in scope, sadly enough you just need to remove the space after "if". Play templates are pretty sensitive about spacing. Try:
<div>
@if(request.uri == "/") { "Home Menu Selected" }
</div>
What you are trying to achieve is quite common, you are trying to show the current page in a menu by marking it as active.
You can indeed do what you did above. Add several @if conditions with string comparisons in your template.
@if(request.uri == "/"){ class="active" }
But I like to go a little further in the type safe architecture. I generally create an object containing a lot of constants :
object MenuContants {
val HOME = "HOME"
val CONTACT = "CONTACT"
}
And then I give those constants around in the templates. From sub-template to the master layout template :
@main("The title of my page", MenuConstants.HOME) {
// the rest of my template
}
And then in your main template, do the comparison but no longer based on strings but on constants, which is type-safe.
@(title:String, contant:String) {
@if(contant == MenuConstants.HOME) { class="active" }
}
To answer the question
The implicit Request, available to the templates, has all the details. Adapted to the example in the question I would use the following template function, which was tested in Play Framework 2.6. It does not require to maintain an enum but you still stay safe when updating your routes
file and get compile errors when you rename the actions.
@*
Usage:
<div>
@outputIf(routes.HomeController.index, "Home Menu Selected")
</div>
*@
@outputIf(call:play.api.mvc.Call, text:String) = @{
if (request.path.equals(call.path)) text else ""
}
Documentation
There is some documentation about reusable blocks: https://www.playframework.com/documentation/2.6.x/ScalaTemplates#Declaring-reusable-blocks
play.api.mvc.Call API: https://www.playframework.com/documentation/2.6.x/api/scala/index.html#play.api.mvc.Call
play.api.mvc.Request API: https://www.playframework.com/documentation/2.6.x/api/scala/index.html#play.api.mvc.Request
My intention (rendering Navigation)
I recently stumbled across a related Problem and after i found nothing specific to my problem on the web aside from this post, i'd like to share my final solution with you.
I'd wanted to render navigation list items with an 'active' class if the current url of the page is equal to the list items' url but neither did I like to just compare the url-string for equality as it may change and would give no compile errors - nor did I accept to create and update an enum every time I add a new navigation item (as I have an increasing amount of them including children). However I still wanted to stay safe when changing the routes
urls at some time.
In Play Framework 2.6 I solved the problem using this reusable function within the main.scala.html
template:
@*
Renders a list item <li> with active-class containing a link element
Usage:
@navItem(routes.HomeController.index, "Home")
@navItem(routes.HomeController.index, "Home", "nav-home")
@navItem(routes.HomeController.index, "Home", activeClass="selected")
@navItem(routes.HomeController.index, "<span>Home</span>", "nav-home nav-element", "selected active")
*@
@navItem(call:play.api.mvc.Call, linkContent:String, cls:String="", activeClass:String="active") = @{
val hrefAttr = "href='"+call+"'"
val classNames = if (request.path.equals(call.path)) activeClass + " " + cls else cls
val classAttr = if(classNames.length>0) " class='"+classNames+"'" else ""
val linkHtml = Html(linkContent)
Html("<li"+classAttr+"><a "+hrefAttr+">"+linkHtml+"</a></li>")
}
the comment example renders to the following in case the Homepage is requested:
<li class="active"><a href="/">Home</a></li>
<li class="active nav-home"><a href="/">Home</a></li>
<li class="selected"><a href="/">Home</a></li>
<li class="selected active nav-home nav-element"><a href="/"><span>Home</span></a></li>
© 2022 - 2024 — McMap. All rights reserved.
@if
and(
that's the only reason and after removing the space it will be OK. – Acetabulum