Last active
August 29, 2015 14:04
-
-
Save xymor/56621e11aad2ff203ad8 to your computer and use it in GitHub Desktop.
Grails CMS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package commerce.catalog.cms | |
import grails.util.* | |
class ComponentTagLib { | |
def storeService, resourceService, groovyPagesTemplateEngine, cacheUtils, grailsApplication, cookieManager | |
def section = { attrs -> | |
def store = storeService.getStore() | |
if(useCache(store)){ | |
def cacheKey = createCacheKey('section', "${store.id}-${attrs.name}", attrs) | |
out << cacheUtils.doWithCacheWithTimeout(cacheKey, grailsApplication.config.cacheUtils.componentTimeOut as Integer){ | |
def section = findSection(attrs.name) | |
if(section){ | |
this.renderComponentsFromSection(section, attrs) | |
} | |
} | |
}else{ | |
def section = findSection(attrs.name) | |
if(section){ | |
out << this.renderComponentsFromSection(section, attrs) | |
} | |
} | |
} | |
def component = { attrs -> | |
def store = storeService.getStore() | |
if(useCache(store)){ | |
def cacheKey = createCacheKey('component', "${store.id}-${attrs.name}", attrs) | |
out << cacheUtils.doWithCacheWithTimeout(cacheKey, grailsApplication.config.cacheUtils.componentTimeOut as Integer){ | |
this.renderComponent(ComponentInstance.findByName(attrs.name, [cache: true, readOnly: true]), attrs) | |
} | |
}else{ | |
out << this.renderComponent(ComponentInstance.findByName(attrs.name, [cache: true, readOnly: true]), attrs) | |
} | |
} | |
def componentMetaDescription = { attrs -> | |
def componentInstance = ComponentInstance.findByName(attrs.name, [cache: true, readOnly: true]) | |
if (componentInstance?.description){ | |
out << "<meta name='description' content='${componentInstance?.description}' />" | |
} | |
} | |
def renderPropComponent = { attrs -> | |
def componentInstance = ComponentInstance.findByIsActiveAndName(true, attrs.name, [cache: true, readOnly: true]) | |
out << componentInstance.props[attrs.prop] | |
} | |
def renderGspProp = { attrs -> | |
def store = storeService.getStore() | |
if(useCache(store)){ | |
def cacheKey = createCacheKey('gspProp', "${store.id}-${attrs.name}", attrs) | |
out << cacheUtils.doWithCacheWithTimeout(cacheKey, grailsApplication.config.cacheUtils.componentTimeOut as Integer){ | |
this.renderTemplateEngineGsp(attrs) | |
} | |
}else{ | |
out << this.renderTemplateEngineGsp(attrs) | |
} | |
} | |
private findSection(name){ | |
def section | |
if(getCurrentComponent()){ | |
section = Section.findByComponentInstanceAndName(getCurrentComponent(), name, [cache: true, readOnly: true]) | |
} | |
if(request.currentPage && !section){ | |
section = Section.findByPageAndName(request.currentPage, name, [cache: true, readOnly: true]) | |
} | |
if(!section){ | |
section = Section.findByName(name, [cache: true, readOnly: true]) | |
} | |
section | |
} | |
private renderTemplateEngineGsp(attrs){ | |
def componentInstance = (attrs.component ?: ComponentInstance.findByIsActiveAndName(true, attrs.name, [cache: true, readOnly: true])) | |
def gspText = this.replaceTemplateVariables(componentInstance.props[attrs.prop]) | |
this.renderGsp(gspText, componentInstance, attrs) | |
} | |
private renderGsp(gspText, componentInstance, attrs){ | |
def output = new StringWriter() | |
if(gspText) { | |
def store = storeService.getStore() | |
def model = [self: componentInstance, props: componentInstance.props, storeInstance: store] + attrs | |
groovyPagesTemplateEngine.createTemplate(gspText, componentInstance.name).make(model).writeTo(output) | |
} | |
this.debugComponent(componentInstance){ | |
output.toString() | |
} | |
} | |
private replaceTemplateVariables(template){ | |
def variablesNames = template.findAll(/\{(\w*)\}/) | |
if(variablesNames){ | |
TemplateEngineVariable.createCriteria().list{ | |
'in'('name', variablesNames) | |
cache true | |
}.each{ | |
template = template.replace(it.name, it.value) | |
} | |
} | |
template | |
} | |
private renderComponentsFromSection(section , attrs) { | |
log.debug "Rendering Section #${section?.id} - Name: ${section?.name}" | |
def componentsHTML = section.activeComponents.collect { componentInstance -> | |
this.renderComponent(componentInstance, attrs) | |
} | |
componentsHTML.join('\n') | |
} | |
private renderComponent(componentInstance, attrs) { | |
this.addComponentToStack(componentInstance) | |
def html = this.renderTemplate(componentInstance, attrs) | |
if(params.editMode && Environment.currentEnvironment != Environment.PRODUCTION) { | |
html = this.render("/components/default/editMode/componentContainer", model:[componentInstance: componentInstance, componentView: html], componentInstance, attrs.debug) | |
} | |
this.removeComponentFromStack() | |
html | |
} | |
private renderTemplate(componentInstance, attrs){ | |
def layoutDirName = storeService.getLayout().theme.directoryName | |
if(componentInstance && componentInstance.isActive && componentInstance.component.content){ | |
return this.renderGsp(componentInstance.component.content, componentInstance, attrs) | |
}else if(componentInstance && componentInstance.isActive && componentInstance.component){ | |
def path = "/components/${layoutDirName}/${componentInstance.component.path}" | |
return this.resolveTemplate(layoutDirName, path, attrs, componentInstance) | |
}else if(!componentInstance){ | |
log.debug("ComponentInstance [${attrs.name}] não encontrado, renderizando componente default.") | |
def path = "/components/${layoutDirName}/${attrs.name}" | |
return this.resolveTemplate(layoutDirName, path, attrs) | |
} | |
} | |
private resolveTemplate(layoutDirName, path, attrs, componentInstance = null){ | |
def debug = attrs.debug != null ? attrs.debug : true | |
def props = (componentInstance ? componentInstance.props : [:]) | |
def instance = componentInstance ?: new Expando(props: [:]) | |
if(resourceExists(path)){ | |
render(path, [self: instance, props: props] + attrs, componentInstance, debug) | |
}else{ | |
render(path.replace("/${layoutDirName}/","/default/"), [self : instance, props: props] + attrs, componentInstance, debug) | |
} | |
} | |
boolean resourceExists(path){ | |
def cacheKey = createCacheKey('componentPath', path, [:]) | |
def exists = cacheUtils.doWithCacheWithTimeout(cacheKey, grailsApplication.config.cacheUtils.gspCheckTimeOut as Integer){ | |
def templatePath = path.split('/') as List | |
templatePath[templatePath.size() - 1] = "_${templatePath.last()}" | |
resourceService.resourceExists("${templatePath.join('/')}", grailsAttributes) | |
} | |
exists | |
} | |
private render(path, model, componentInstance, debug){ | |
if(componentInstance && debug){ | |
this.debugComponent(componentInstance){ | |
g.render(template: path, model: params + model + [storeInstance: storeService.getStore()]) | |
} | |
}else{ | |
g.render(template: path, model: params + model + [storeInstance: storeService.getStore()]) | |
} | |
} | |
private debugComponent(componentInstance, closure){ | |
""" | |
<div component-id="${componentInstance?.id}" name="${componentInstance?.name}" class="component"> | |
${closure()} | |
</div> | |
""" | |
} | |
private useCache(store){ | |
store.enterprise && !new Boolean(request.skipCache) | |
} | |
private createCacheKey(cacheName, key, attrs){ | |
def themeId = storeService.getLayout().theme.id | |
if(getCoupon()){ | |
"${cacheName}-${key}-${attrs}-${themeId}-${params}-${getCoupon()}".hashCode().toString() | |
}else{ | |
"${cacheName}-${key}-${attrs}-${themeId}-${params}".hashCode().toString() | |
} | |
} | |
private getCoupon() { | |
params.cupom ?: new String(cookieManager.getCouponCookie(storeService.store.symbol, request.cookies)?.value?.decodeBase64() ?: "") | |
} | |
private addComponentToStack(componentInstance){ | |
if(!request.componentStack){ | |
request.componentStack = [] | |
} | |
request.componentStack << componentInstance | |
} | |
private removeComponentFromStack(){ | |
request.componentStack.pop() | |
} | |
private getCurrentComponent(){ | |
request.componentStack?.isEmpty() ? null : request.componentStack?.last() | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def groovyPagesTemplateEngine | |
def index = { | |
request.currentPage = this.findPage() | |
if(request.currentPage?.content){ | |
this.renderPage(request.currentPage) | |
}else{ | |
render view: this.getViewPath(request.currentPage), model: params + [storeInstance: storeService.getStore(), props: request.currentPage?.props] | |
} | |
} | |
private findPage(page = params.page){ | |
if(request.currentPage){ | |
request.currentPage | |
}else if(params.pageId){ | |
Page.findById(params.pageId as Long, [cache: true, readOnly: true]) | |
}else{ | |
Page.findByPath(page, [cache: true, readOnly: true]) | |
} | |
} | |
private renderPage(page, model = [:]){ | |
log.debug "Renderizando conteúdo customizado de página" | |
def output = new StringWriter() | |
def store = storeService.getStore() | |
groovyPagesTemplateEngine.createTemplate(page.content, "page_${page.id}") | |
.make(params + [storeInstance: store, props: page?.props] + model).writeTo(output) | |
render text: output.toString() | |
} | |
private getViewPath(page = null){ | |
def view = "/stores/${storeService.getLayout().theme.directoryName}/${page?.path ?: params.page}" | |
(resourceExists(view) ? view : "/stores/default/${params.page}") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment