【问题标题】:PlayFramework2 how to get current page's URL in view templatesPlay Framework 2 如何在视图模板中获取当前页面 URL
【发布时间】:2013-09-21 07:06:03
【问题描述】:

最初在这里发布和回答:

https://groups.google.com/forum/#!topic/play-framework/s-ufMIbLz3c

但是当我把:

<div>
 @if (request.uri == "/") { "Home Menu Selected" }
</div>

但我得到了:

'(' expected but ')' found.

【问题讨论】:

  • 正如 Karl 所写,这是由 @if( 之间的空格引起的,这是唯一的原因,删除空格后就可以了。

标签: scala playframework-2.0


【解决方案1】:

假设您在范围内有请求对象,遗憾的是您只需要删除“if”之后的空格。播放模板对间距非常敏感。试试:

<div>
 @if(request.uri == "/") { "Home Menu Selected" }
</div>

【讨论】:

【解决方案2】:

您要实现的目标很常见,您试图通过将当前页面标记为活动来在菜单中显示当前页面。

解决方案 1

你确实可以做你上面所做的。在模板中添加几个带有字符串比较的 @if 条件。

@if(request.uri == "/"){ class="active" }

解决方案 2

但我喜欢在类型安全架构上走得更远一点。我通常会创建一个包含很多常量的对象:

object MenuContants {
    val HOME = "HOME"
    val CONTACT = "CONTACT"
}

然后我在模板中给出这些常量。从子模板到主布局模板:

@main("The title of my page", MenuConstants.HOME) {
    // the rest of my template
}

然后在您的主模板中进行比较,但不再基于字符串而是基于常量,这是类型安全的。

@(title:String, contant:String) {
    @if(contant == MenuConstants.HOME) { class="active" }
}

【讨论】:

  • 很高兴看到符合类型安全方法的解决方案。
  • 对于解决方案 2,任何字符串值(不仅仅是 MenuContants 中定义的值)都可以作为“contant”传入。这似乎需要更多的仪式,并提供更多出错的机会(因为匆忙的人可能会不小心从 MenuContants 中选择错误的值)。这个解决方案如何更安全?
  • 你应该使用类中定义的常量。但实际上,没有任何限制。任何字符串都可以。但是,如果您真的想更进一步,您可以创建扩展母接口的案例类。但我不认为这是值得的。
【解决方案3】:

回答问题

模板可用的隐式请求包含所有详细信息。适应问题中的示例,我将使用以下模板函数,该函数在 Play Framework 2.6 中进行了测试。它不需要维护枚举,但在更新 routes 文件时仍然保持安全,并且在重命名操作时会出现编译错误。

@*
  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 ""
}

文档

一些关于可重用块的文档: 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

我的意图(渲染导航)

我最近偶然发现了一个相关的问题,除了这篇文章之外,我在网络上没有发现任何特定于我的问题的具体问题,我想与您分享我的最终解决方案。

如果页面的当前 url 等于列表项的 url,我想用“活动”类呈现导航列表项,但我也不喜欢只比较 url 字符串的相等性,因为它可能更改并且不会给出编译错误 - 我也不接受每次添加新导航项时创建和更新枚举(因为我有越来越多的导航项,包括儿童)。但是,在某些时候更改 routes 网址时,我仍然希望保持安全。 在 Play Framework 2.6 中,我使用 main.scala.html 模板中的这个可重用函数解决了这个问题:

@*
  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>")
}

如果主页被请求,评论示例呈现如下:

<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>

【讨论】:

    猜你喜欢
    • 2010-10-23
    • 2014-01-19
    • 2011-05-25
    • 2011-03-15
    • 1970-01-01
    • 2011-07-27
    • 2019-09-19
    • 1970-01-01
    相关资源
    最近更新 更多