/
MenuTagLib.groovy
123 lines (104 loc) · 2.88 KB
/
MenuTagLib.groovy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package se.lagrummet
import groovy.xml.MarkupBuilder
class MenuTagLib {
def page
/**
* Renders a menu based on a page tree
* @attr root REQUIRED the page node from which the menu will be generated, identified by the permalink. the root is not itself included in the menu, only its children
* @attr headerStyles a list of css classes which will be applied to top level menu headers
* @attr rootTag a tag that will wrap the menu as root element
* @attr activePage the page that is currently viewed will be highlighted as "active" in the menus
*
*/
def menu = { attrs, body ->
if(!attrs.root) {
throwTagError("Tag [menu] is missing required attribute [root]")
}
def headerStyles = []
if(attrs.headerStyles) {
headerStyles = attrs.headerStyles
}
def rootTag = null
if(attrs.rootTag) {
rootTag = attrs.rootTag
}
page = null
if(attrs.activePage) {
page = attrs.activePage
}
def now = new Date()
def rootNode = Page.withCriteria(uniqueResult:true) {
eq("permalink", attrs.root)
eq("status", "published")
le('publishStart', now)
or {
ge('publishStop', now)
isNull('publishStop')
}
maxResults(1)
}
if(!rootNode){
return false
}
def writer = new StringWriter()
def xml = new MarkupBuilder(writer)
xml.setOmitEmptyAttributes(true)
xml.setOmitNullAttributes(true)
int i = 0
int size = headerStyles.size()
if(rootTag) {
xml."$rootTag" {
buildMenu(xml, rootNode, body)
}
} else {
buildMenu(xml, rootNode, body)
}
out << writer.toString()
}
def buildMenu(builder, rootNode, body) {
rootNode.publishedChildren.each { node ->
if(node.metaPage) {
subMenu(builder, node)
} else {
createListElement(builder, node)
}
}
if(body) {
builder.getMkp().yieldUnescaped(body())
}
}
def subMenu(builder, metaNode) {
builder.ul('class':metaNode.menuStyle) {
li('class':'heading', metaNode.title)
metaNode.publishedChildren.each{ node ->
createListElement(builder, node)
}
}
}
def createHeadlessList(builder, nodes) {
builder.ul {
nodes.each { node ->
createListElement(builder, node)
}
}
}
def createListElement(builder, node) {
def active = ""
if(node.permalink == page?.permalink){
active = "active"
}
builder.li('class':active) {
if(node.metaPage) {
subMenu(builder, node)
} else if(node.publishedChildren.size() > 0) {
createLinkElement(builder, node)
createHeadlessList(builder, node.publishedChildren)
} else {
createLinkElement(builder, node)
}
}
}
def createLinkElement(builder, node) {
builder.a(href:createLink(mapping:'page', params:[permalink:node.url()]), node.title)
}
}