@@ -7,16 +7,12 @@ import grails.util.Environment
7
7
import groovy.text.GStringTemplateEngine
8
8
import groovy.text.Template
9
9
import groovy.transform.CompileStatic
10
- import org.grails.buffer.*
10
+ import org.grails.buffer.FastStringWriter
11
11
import org.grails.web.servlet.mvc.GrailsWebRequest
12
12
import org.grails.web.servlet.view.GroovyPageView
13
13
import org.grails.web.servlet.view.GroovyPageViewResolver
14
14
import org.springframework.context.ResourceLoaderAware
15
- import org.springframework.core.io.ByteArrayResource
16
- import org.springframework.core.io.FileSystemResource
17
- import org.springframework.core.io.Resource
18
- import org.springframework.core.io.ResourceLoader
19
- import org.springframework.core.io.UrlResource
15
+ import org.springframework.core.io.*
20
16
import org.springframework.web.servlet.View
21
17
22
18
import java.util.concurrent.ConcurrentHashMap
@@ -27,6 +23,39 @@ import java.util.concurrent.ConcurrentHashMap
27
23
*/
28
24
@CompileStatic
29
25
class ScaffoldingViewResolver extends GroovyPageViewResolver implements ResourceLoaderAware , ModelBuilder {
26
+ final Class templateOverridePluginDescriptor
27
+
28
+ public ScaffoldingViewResolver () {
29
+ this . templateOverridePluginDescriptor = null
30
+ }
31
+
32
+ /**
33
+ * This constructor allows a plugin to override the default templates provided by the Scaffolding
34
+ * plugin. The plugin that contains the template override should be configured to load AFTER the
35
+ * scaffolding plugin. An example implementation follows:
36
+ *
37
+ * <pre >
38
+ * {@code
39
+ * def loadAfter = ['scaffolding']
40
+ * }
41
+ * </pre>
42
+ * ...
43
+ * <pre >
44
+ * {@code
45
+ * @Override
46
+ * Closure doWithSpring() { { ->
47
+ * jspViewResolver(ScaffoldingViewResolver, this.class) { bean ->
48
+ * bean.lazyInit = true
49
+ * bean.parent = "abstractViewResolver"
50
+ * }
51
+ * }}
52
+ * </pre>
53
+ *
54
+ * @param templateOverridePluginDescriptor
55
+ */
56
+ public ScaffoldingViewResolver (Class templateOverridePluginDescriptor ) {
57
+ this . templateOverridePluginDescriptor = templateOverridePluginDescriptor
58
+ }
30
59
31
60
ResourceLoader resourceLoader
32
61
protected Map<String , View > generatedViewCache = new ConcurrentHashMap<> ()
@@ -43,42 +72,46 @@ class ScaffoldingViewResolver extends GroovyPageViewResolver implements Resource
43
72
@Override
44
73
protected View loadView (String viewName , Locale locale ) throws Exception {
45
74
def view = super . loadView(viewName, locale)
46
- if (view == null ) {
75
+ if (view == null ) {
47
76
String cacheKey = buildCacheKey(viewName)
48
77
view = generatedViewCache. get(cacheKey)
49
- if (view != null ) {
78
+ if (view != null ) {
50
79
return view
51
- }
52
- else {
80
+ } else {
53
81
def webR = GrailsWebRequest . lookup()
54
82
def controllerClass = webR. controllerClass
55
83
56
84
def scaffoldValue = controllerClass?. getPropertyValue(" scaffold" )
57
- if (scaffoldValue instanceof Class ) {
85
+ if (scaffoldValue instanceof Class ) {
58
86
def shortViewName = viewName. substring(viewName. lastIndexOf(' /' ) + 1 )
59
87
Resource res = null
60
88
61
- if (Environment . isDevelopmentMode()) {
89
+ if (Environment . isDevelopmentMode()) {
62
90
res = new FileSystemResource (new File (BuildSettings . BASE_DIR , " src/main/templates/scaffolding/${ shortViewName} .gsp" ))
63
91
}
64
92
65
- if (! res?. exists()) {
93
+ if (! res?. exists()) {
66
94
def url = IOUtils . findResourceRelativeToClass(controllerClass. clazz, " /META-INF/templates/scaffolding/${ shortViewName} .gsp" )
67
95
res = url ? new UrlResource (url) : null
68
96
}
69
97
70
- if (! res. exists()) {
98
+ if (! res. exists() && templateOverridePluginDescriptor) {
99
+ def url = IOUtils . findResourceRelativeToClass(templateOverridePluginDescriptor, " /META-INF/templates/scaffolding/${ shortViewName} .gsp" )
100
+ res = url ? new UrlResource (url) : null
101
+ }
102
+
103
+ if (! res. exists()) {
71
104
res = resourceLoader. getResource(" classpath:META-INF/templates/scaffolding/${ shortViewName} .gsp" )
72
105
}
73
106
74
- if (res. exists()) {
75
- def model = model((Class )scaffoldValue)
107
+ if (res. exists()) {
108
+ def model = model((Class ) scaffoldValue)
76
109
def viewGenerator = new GStringTemplateEngine ()
77
110
Template t = viewGenerator. createTemplate(res.URL )
78
111
79
112
def contents = new FastStringWriter ()
80
113
t. make(model. asMap()). writeTo(contents)
81
-
114
+
82
115
def template = templateEngine. createTemplate(new ByteArrayResource (contents. toString(). getBytes(templateEngine. gspEncoding), " view:$cacheKey " ))
83
116
view = new GroovyPageView ()
84
117
view. setServletContext(getServletContext())
@@ -88,8 +121,7 @@ class ScaffoldingViewResolver extends GroovyPageViewResolver implements Resource
88
121
view. afterPropertiesSet()
89
122
generatedViewCache. put(cacheKey, view)
90
123
return view
91
- }
92
- else {
124
+ } else {
93
125
return view
94
126
}
95
127
0 commit comments