Permalink
Browse files

Migration to github

  • Loading branch information...
0 parents commit bfd5879d04c241c0cc79728a4d00836e6f8509fe @marcpalmer marcpalmer committed Feb 3, 2012
@@ -0,0 +1,62 @@
+class NavigationGrailsPlugin {
+ def version = '1.3.2'
+
+ // the version or versions of Grails the plugin is designed for
+ def grailsVersion = "1.2 > *"
+
+ def dependsOn = [controllers:"1.0 > *"]
+ def observe = ['controllers']
+ def loadAfter = ['logging']
+
+ def author = "Marc Palmer"
+ def authorEmail = "marc@grailsrocks.com"
+ def title = "Site Menu Navigation"
+ def description = '''\
+Tags for doing site navigation and menus by convention
+'''
+ def documentation = "http://grails.org/Navigation+Plugin"
+
+ def doWithSpring = {
+ // TODO Implement runtime spring config (optional)
+ }
+
+ def doWithApplicationContext = { applicationContext ->
+ }
+
+ def doWithWebDescriptor = { xml ->
+ // TODO Implement additions to web.xml (optional)
+ }
+
+ def doWithDynamicMethods = { ctx ->
+ refreshNavigation(application, applicationContext)
+ }
+
+ def onChange = { event ->
+ if (event.source instanceof Class) {
+ refreshNavigation(application, applicationContext)
+ }
+ }
+
+ private refreshNavigation(application, applicationContext) {
+ def navSrv = applicationContext.navigationService
+ navSrv.reset()
+
+ application.controllerClasses.each { controllerClass ->
+ // If there is a navigation property that is not null or false, we include it
+ def nav = false
+ if (controllerClass.clazz.metaClass.hasProperty(controllerClass.clazz, 'navigation')) {
+ nav = controllerClass.clazz.navigation
+ }
+ if (nav) {
+ navSrv.registerItem(controllerClass)
+ }
+ }
+
+ navSrv.updated()
+ }
+
+ def onConfigChange = { event ->
+ // TODO Implement code that is executed when the project configuration changes.
+ // The event is the same as for 'onChange'.
+ }
+}
@@ -0,0 +1,6 @@
+#Grails Metadata file
+#Fri Jul 29 12:57:45 BST 2011
+app.grails.version=1.3.7
+app.name=Navigation
+plugins.hibernate=1.3.7
+plugins.tomcat=1.3.7
@@ -0,0 +1,32 @@
+dataSource {
+ pooled = true
+ driverClassName = "org.hsqldb.jdbcDriver"
+ username = "sa"
+ password = ""
+}
+hibernate {
+ cache.use_second_level_cache=true
+ cache.use_query_cache=true
+ cache.provider_class='com.opensymphony.oscache.hibernate.OSCacheProvider'
+}
+// environment specific settings
+environments {
+ development {
+ dataSource {
+ dbCreate = "create-drop" // one of 'create', 'create-drop','update'
+ url = "jdbc:hsqldb:mem:devDB"
+ }
+ }
+ test {
+ dataSource {
+ dbCreate = "create-drop"
+ url = "jdbc:hsqldb:mem:testDb"
+ }
+ }
+ production {
+ dataSource {
+ dbCreate = "update"
+ url = "jdbc:hsqldb:file:prodDb;shutdown=true"
+ }
+ }
+}
@@ -0,0 +1,5 @@
+modules = {
+ 'navigation.plugin' {
+ resource url:[plugin:'navigation', dir:'css', file:'navigation.css']
+ }
+}
@@ -0,0 +1,11 @@
+class UrlMappings {
+ static mappings = {
+ "/$controller/$action?/$id?"{
+ constraints {
+ // apply constraints here
+ }
+ }
+ "/"(view:"/index")
+ "500"(view:'/error')
+ }
+}
@@ -0,0 +1,202 @@
+import org.codehaus.groovy.grails.commons.GrailsControllerClass
+import org.codehaus.groovy.grails.commons.ConfigurationHolder
+import org.codehaus.groovy.grails.commons.GrailsClassUtils
+
+// @todo subItem sorting
+class NavigationService {
+
+ static transactional = false
+
+ def manuallyRegistered = []
+ def byGroup = ['*':[]]
+ def hidden = new HashSet()
+ def activePathByRequestArgs = [:]
+
+ def reset() {
+ byGroup = ['*':[]]
+ // re-add the manually defined items
+ ConfigurationHolder.config.navigation?.each { k, v ->
+ doRegisterItem(k, v)
+ }
+ manuallyRegistered.each { item ->
+ doRegisterItem(item.group, item.info)
+ }
+ }
+
+ protected newSubItem(data, controllerName) {
+ def result = [:]
+ if (data instanceof Map) {
+ result.putAll(data)
+ } else {
+ result.action = data
+ }
+ if (!result.title) {
+ result.title = GrailsClassUtils.getNaturalName(result.action)
+ }
+ result.controller = controllerName
+
+ calculatePath(result.path, result)
+
+ return result
+ }
+
+ def makeReverseMapKey(controller, action, params) {
+ def k = "$controller/$action"
+ if (params?.size()) {
+ def p = new TreeMap(params)
+ p.remove('controller')
+ p.remove('action')
+ if (p) {
+ k += '/' + p.toString()
+ }
+ }
+ return k.toString()
+ }
+
+ def reverseMapActivePathFor(controller, action, params) {
+ // Try first with params
+ def kWithParams = makeReverseMapKey(controller, action, params)
+ def path = activePathByRequestArgs[kWithParams]
+ if (!path) {
+ def kWithoutParams = makeReverseMapKey(controller, action, null)
+ path = activePathByRequestArgs[kWithoutParams]
+ }
+ return path ?: kWithParams.tokenize('/')
+ }
+
+ void calculatePath(pathValue, item) {
+ if (pathValue) {
+ item.path = pathValue instanceof List ? pathValue : pathValue.tokenize('/')
+ } else {
+ item.path = [item.controller, item.action]
+ if (item.params) {
+ def sortedParams = new TreeMap()
+ sortedParams += item.params
+ item.path << sortedParams.toString()
+ }
+ }
+ }
+
+ def populateItem(src, item, controllerGrailsClass) {
+ item.action = src.action ?: (controllerGrailsClass ? controllerGrailsClass.defaultAction : 'index')
+ item.order = src.order
+ item.id = src.id
+ item.isVisible = (src['isVisible'] == null) ? true : src.isVisible
+ item.title = src.title ?: GrailsClassUtils.getNaturalName(src.action)
+ item.params = src.params
+
+ calculatePath(src.path, item)
+
+ item.subItems = src.subItems?.collect { subitem ->
+ def si = newSubItem(subitem, item.controller)
+ def k = makeReverseMapKey(si.controller, si.action, si.params)
+ activePathByRequestArgs[ k ] = si.path
+ return si
+ }
+ return item
+ }
+
+ /**
+ * Register a navigation item by convention
+ */
+ def registerItem(GrailsControllerClass controllerGrailsClass) {
+ def p = [
+ controller:controllerGrailsClass.logicalPropertyName
+ ]
+ def grp
+ def navInfo = '*'
+ if (controllerGrailsClass.clazz.metaClass.hasProperty(controllerGrailsClass.clazz, 'navigation')) {
+ navInfo = controllerGrailsClass.clazz.navigation
+ if (navInfo == false) {
+ return
+ }
+ if (navInfo == true) {
+ navInfo = '*'
+ }
+ }
+ if (navInfo instanceof Map) {
+ populateItem(navInfo, p, controllerGrailsClass)
+
+ grp = navInfo.group
+ } else if (navInfo instanceof List) {
+ // Handle lists of info
+ navInfo.each { info ->
+ def params = [:]
+ params.controller = p.controller
+ populateItem(info, params, controllerGrailsClass)
+
+ if (info.group) grp = info.group // use last one unless there is a new one
+
+ doRegisterItem(grp, params)
+ }
+ return
+ } else {
+ grp = navInfo
+ }
+ if (!p.action) {
+ p.action = controllerGrailsClass.defaultAction
+ }
+ if (!p.title) {
+ p.title = GrailsClassUtils.getNaturalName(controllerGrailsClass.name)
+ }
+ doRegisterItem(grp, p)
+ }
+
+ /**
+ * Manually register a navigation item
+ */
+ def registerItem(String group, params) {
+ def item = doRegisterItem(group, params)
+ manuallyRegistered << [group:group, info:item]
+ }
+
+ protected doRegisterItem(String group, Collection v) {
+ v.eachWithIndex { item, n -> doRegisterItem(group, item, n) }
+ }
+
+ protected doRegisterItem(String group, Map params, defaultOrderValue = null) {
+ params.action = params.action ?: 'index' // @todo should be default action of controller
+
+ def item = [:]
+ item.controller = params.controller
+ if (!params.order) {
+ params.order = defaultOrderValue
+ }
+ populateItem(params, item, null)
+
+ def k = makeReverseMapKey(item.controller, item.action, item.params)
+ activePathByRequestArgs[ k ] = item.path
+
+ if (!group) group = '*'
+
+ def catInfo = byGroup[group]
+ if (!catInfo) {
+ catInfo = byGroup[group] = []
+ }
+ catInfo << item
+ if (group != '*') {
+ byGroup['*'] << item
+ }
+
+ return item
+ }
+
+ def hide(String controller) {
+ hidden << controller
+ }
+
+ /**
+ * Must be called after you have registered your items, to enforce ordering
+ */
+ def updated() {
+ byGroup.keySet().each { k ->
+ byGroup[k] = byGroup[k].findAll { info -> !hidden.contains(info.controller) }
+ byGroup[k] = byGroup[k]?.sort { a, b ->
+ if (b.order) {
+ return a.order?.compareTo(b.order) ?: 0
+ } else return +1 // items with no ordering come last
+ }
+ }
+ log.info "Navigation items updated: ${byGroup}"
+ }
+}
Oops, something went wrong.

0 comments on commit bfd5879

Please sign in to comment.