Taglibs aninhadas
22/10/2013 09:46
0
Como posso criar um conjunto de taglibs que interajam entre si mais ou menos assim:

<g:foo>
<g:bar param="xpto"/>
<g:bar param="xyz"/>
<g:bar param="abc"/>
</g:foo>


A tag "bar" por si só não vai gerar nenhuma saída, mas os seus parametros devem ser armazenados, pois a tag foo, após executar todas as tags internas, vai reunir estes dados e gerar uma única saída, que envolve html e javascript

Minha dúvida é como invocar as tags internas e armazenar os seus parametros e só depois de tudo gerar o output
Tags: taglib


0
Olá, Magno.

Acredito que pode fazer isso setando variáveis no escopo de página na "tag pai" que poderão ser lidos pelas "filhas".
Nunca precisei fazer isso mas é isso que tentaria.

Abraços.


0
José Yoshihiro,
Obrigado pela resposta
De fato, tinha que usar a variável pageScope para guardar objetos que podem ser acessados pelas diversas tags.

Estou utilizando isso para criar uma taglib para plotar grárficos via jqplot...
Já tenho algo funcional, mas preciso amadurecer e flexibilizar algumas coisas, por enquanto estou usando interno numa aplicação, mas pretendo liberar como um plugin posteriormente.
Segue exemplo de uso das taglibs:
<chart:plot>
<g:each in="${data}" var="ano">
<chart:serie label="${ano.key}">
<g:each in="${ano.value}">
<chart:data x="${meses[it[2] - 1]}" y="${it[0] + it[1]}"/>
</g:each>
</chart:serie>
</g:each>
</chart:plot>


E a implementação da taglib:


class JqPlotTagLib {

static namespace = 'chart'

static class Serie {
def x = []
def y = []
String label
}

static class Dataset {
List x = []
List y = []
List labels = []

def Dataset(series) {
Integer maxSize = series.collect({it.x.size()}).max()

for (int i = 0; i < maxSize; ++i) {
for (Serie s : series) {
if (i < s.x.size()) {
if (!x.contains(s.x[i]))
x << s.x[i]
}
}
}

series.each { Serie s ->
def serieY = []
y << serieY
labels << s.label
x.each {
int idx = s.x.indexOf(it)
if (idx == -1)
serieY << null
else
serieY << s.y[idx]
}
}
}
}

private dontEscape(o) {
return { o }
}

private toJavascript(o) {
def out = new StringBuffer()
if (o instanceof List) {
out << "["
out << o.collect({toJavascript(it)}).join(", ")
out << "]"
}
else if (o instanceof Map) {
out << "{"
out << o.collect({"${it.key}: ${toJavascript(it.value)}"}).join(", ")
out << "}"
}
else if (o instanceof String)
out << "\"" + o + "\""
else if (o instanceof Closure)
out << o.call()
else
out << o.toString()

return out.toString()
}

def plot = { attrs, body ->
def series = []
pageScope.chartSeriesContainer = series
body()

def ds = new Dataset(series)

out << "<div id=\"chartdiv\"></div>"

g.javascript [:], {
def options = [:]
options.seriesDefaults = [
renderer: dontEscape("\$.jqplot.BarRenderer"),
renderOptions: [fillToZero: true]
]
options.series = ds.labels.collect { [label: it] }
options.axes = [
xaxis: [
renderer: dontEscape("\$.jqplot.CategoryAxisRenderer"),
ticks: dontEscape("ticks")
],
yaxis: [
pad: 1.05,
tickOptions: [formatString: "\$%d"]
]
]

def out = new StringBuilder()

out << "\$(function() {\n"
ds.labels.eachWithIndex { serie, i ->
out << "var s${i} = [${ds.y[i].join(', ')}];\n"
}
out << "var ticks = ${toJavascript(ds.x)};"
out << "\$.jqplot('chartdiv', ["
out << (0..series.size() - 1).collect({ "s${it}" }).join(",")

out << "], "
out << toJavascript(options)
out << ")});"

out.toString()
}
}

def serie = { attrs, body ->
def serie = new Serie()
serie.label = attrs.label
pageScope.chartSerie = serie
pageScope.chartSeriesContainer << serie
body()
}

def data = { attrs ->
def serie = pageScope.chartSerie
serie.x << attrs.x
serie.y << attrs.y
}

}



Ainda não faz parte da comunidade???

Para se registrar, clique aqui.


Aprenda Groovy e Grails com a Formação itexto!

Newsletter Semana Groovy

Assinar

Envie seu link!


Livro de Grails


/dev/All

Os melhores blogs de TI (e em português) em um único lugar!

 
Creative Commons
RSS Grails Brasil é mantido por itexto Consultoria.
Em caso de problemas contacte Henrique Lobo Weissmann (Kico) por e-mail: kico@itexto.com.br
Todo o conteúdo presente neste site adota o Creative Commons como licença padrão.
Ver: 4.14.0
itexto