我找到了一个Grails框架来生成Breadcrumbs here。它确实根据breadcrumbs.xml文件中的静态定义生成面包屑,它定义了面包屑的层次结构:
<map>
<nav id="homeCrumb" matchController="samplePages" matchAction="homeBreadCrumbPage">
<!-- levels navigation -->
<nav id="itemsLevel1Crumb" matchController="samplePages" matchAction="level1BreadCrumbPage">
<nav id="itemsLevel2Crumb" matchController="samplePages" matchAction="level2BreadCrumbPage">
<nav id="itemsLevel3Crumb" matchController="samplePages" matchAction="level3BreadCrumbPage">
<nav id="showItemCrumb" matchController="samplePages" matchAction="itemDetailsBreadCrumbPage"/>
</nav>
</nav>
</nav>
<nav id="simple1Crumb" matchController="samplePages" matchAction="simpleBreadCrumb"/>
<nav id="simple2Crumb" matchController="samplePages" matchAction="simpleBreadCrumbWithAttr"/>
<!-- levels navigation -->
</nav>
</map>
此文件由taglib评估和打印:
class BreadCrumbTagLib {
static def log = LogFactory.getLog("grails.app.breadCrumbTag")
def breadCrumb = { attrs , body ->
def manager = BreadCrumbManager.getInstance()
def uri = request.getRequestURI()
def context = request.getContextPath()
def controller = params.controller
def action = params.action
def attrTitle = attrs.title
def attrLink = attrs.link
// if controller and action are missing from params try to get them from request url
if (!controller && !action && uri && context && uri.indexOf(context) != -1) {
def uriParams = uri.substring(uri.indexOf(context) + (context.length() + 1), uri.length())
def uriArray = uriParams.split('/')
if (uriArray.size() >= 2 ) {
controller = uriArray[0]
action = uriArray[1]
}
}
def crumbs = manager.getBreadCrumbs(controller, action)
if (crumbs) {
out << '<div class="breadcrumb"><ul>'
def size = crumbs.size()
crumbs.eachWithIndex { crumb, index ->
out << '<li>'
// override title and link of breadcrumb on current page (i.e. last bread crumb in hierarchy)
// if name, link attributes are supplied
if (index == size - 1) {
if (attrTitle)
crumb.title = attrTitle
if (attrLink)
crumb.link = attrLink
}
// set title to undefined if not found, associated
// renderer if present can overwrite it
if (!crumb.title)
crumb.title = "undefined"
if (crumb.title && crumb.title.size() > 40)
crumb.title = crumb.title.substring(0, 40) + "..."
if (crumb.viewController && crumb.viewAction) {
def content = g.include(controller:crumb.viewController, action:crumb.viewAction, breadcrumb:crumb, params:params)
out << content
} else if (crumb.viewTemplate) {
def content = g.include(view:crumb.viewTemplate, breadcrumb:crumb, params: params)
out << content
} else if (crumb.linkToController && crumb.linkToAction && (size - 1 > index)){
out << "<a href=\"${g.createLink (controller: crumb.linkToController, action: crumb.linkToAction)}\">${crumb.title}</a>"
// if crumb has a link and its not the last vread crumb then show link else
// just show the text
} else if (crumb.link && (size - 1 > index)){
out << "<a href=\"${crumb.link}\">${crumb.title}</a>"
} else {
out << "${crumb.title}"
}
out << "</li>"
// do not print for last bread crumb
if (size - 1 > index)
out << "<li>»</li>"
}
out << "</ul></div>"
}
}
}
问题:当我有一个结构,我需要一些没有修复的参数。
示例:我处于第三级导航中,可以说
A1 / A2 / A3
在我的情况下A2
应该打开像user/show/1234
这样的页面,其中1234是要显示的用户的ID。问题是我无法在breadcrumbs.xml文件中添加1234硬编码,因为此ID会根据您要显示的用户而改变。
如果中间面包屑链接需要动态参数,我该如何处理?
答案 0 :(得分:1)
看起来您的面包屑的格式为CONTROLLER / ACTION / ID。如果是这样,您需要的信息已通过webRequest属性在您的GSP中提供。以下是使用Twitter Bootstrap面包屑的示例:
<ol class="breadcrumb">
<li><a href="#">${webRequest.controllerName}</a></li>
<li><a href="#">${webRequest.actionName}</a></li>
<li class="active">${webRequest.id}</li>
</ol>
您仍然需要将href设置为有意义的内容。一种更强大的方法就是这样......
<g:set var="crumbs" value="${[webRequest.controllerName, webRequest.actionName, webRequest.id].findAll { it != null }}.collect { [label: it, active: false] }" />
<% crumbs.last().active = true %>
<ol class="breadcrumb">
<g:each in="${crumbs}">
<li class="${it.active ? 'active' : ''}"><a href="#">${it.label}</a></li>
</g:each>
</ol>
通过&lt; %%&gt;将Groovy代码嵌入到GSP中不建议使用标签,但可以在TagLib中完成此类操作。这种方法可以处理长度为1-3个部分的面包屑。它根据当前URI进行调整。
答案 1 :(得分:1)
在考虑了一些之后,我意识到最好不要使用HttpSession。如果您使用会话范围的服务,则更容易对面包屑代码进行单元测试。
首先,创建一个会话范围的服务来维护用户的导航历史记录。
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:drawSelectorOnTop="false"
/>
<android.support.design.widget.FloatingActionButton
android:id="@+id/refresh"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|right"
android:layout_marginBottom="@dimen/fab_margin"
android:layout_marginRight="@dimen/fab_margin"
android:src="@drawable/ic_refresh_black_24dp"/>
</android.support.design.widget.CoordinatorLayout>
在您的控制器中注入服务并使用它来跟踪用户的位置。然后将历史记录添加为动作模型返回的内容的一部分:
class NavigationHistoryService {
static transactional = false
static scope = "session"
def history = [:]
public List push(String controller, String action, Map params) {
def crumb = [
action: action,
params: params]
history.controller = crumb
return history
}
最后,使用GSP中的历史记录来渲染碎屑。
class CompanyController {
def navigationHistoryService
def show() {
navigationHistoryService.push('company', 'show', params)
...
[crumbs: navigationHistoryService.history]
}
}
答案 2 :(得分:0)
use simple by blade view
<ul class="breadcrumb" style="padding-right: 20px">
<li> <i class="fa fa-home"></i> <a class="active" href="{{url('/')}}">Home</a>
{{--<i class="fa fa-angle-right"></i>--}}
</li> <?php $link = url('/') ; ?>
@for($i = 1; $i <= count(Request::segments()); $i++)
<li>
@if($i < count(Request::segments()) & $i > 0)
<?php $link .= "/" . Request::segment($i); ?>
<a class="active" href="<?= $link ?>">{{Request::segment($i)}}</a>
{{--{!!'<i class="fa fa-angle-right"></i>'!!}--}}
@else {{Request::segment($i)}}
@endif
</li>
@endfor
</ul>