Na terceira reportagem da série pelos 93 anos da capital, Bolha percorre as árvores, os parques e as escolhas que fizeram a cidade florescer. Ou perder a sombra.
____________________________________________________
Antes das Esmeraldas havia uma Moreira. Melhor, uma Morus ou Morácea. É assim que os botânicos reconhecem cientificamente a árvore frutífera que produz a amora e cujas folhas ainda servem de alimento para o bicho-da-seda. Nos primeiros anos da construção de Goiânia, Pedro Ludovico despachava sob a copa de uma árvore moreira na Rua 24.
Enquanto o Palácio das Esmeraldas era erguido (demorou 4 anos para ser concluído em 1937), uma mesa debaixo da árvore servia ao trabalho do interventor na nova capital. A lembrança atravessou gerações e deu àquele endereço o título simbólico de primeiro “Palácio do Governo”.

A natureza oferecia cobertura ao poder público muito antes de o poder público criar repartições para cuidar da natureza. A árvore não existe mais. Foi tombada em 2008 e três anos depois desapareceu da paisagem. Ela figura como “derrubada” em registro do patrimônio público. Ficou a história – uma espécie de certidão de nascimento que Goiânia deveria consultar com mais frequência.
Ainda hoje, as árvores conseguem interromper a cidade. Na floração dos ipês, Goiânia dispensa qualquer departamento de publicidade. A cidade pode estar atrasada, irritada, em obras, mas basta uma copa se vestir de amarelo, roxo, rosa ou branco para que alguém levante o celular e registre a foto (vale sublinhar que há também os flamboyants e as paineiras-barrigudas). Por alguns segundos, a capital volta a merecer atenção. Uma pequena vitória da árvore sobre a pressa. E uma lembrança da exuberância que temos por aqui.
/**
* nwe-wp-gallery.js
*
* Extraído do bundle (public.js) para uso em arquivo separado.
* Requer:
* – jQuery (window.jQuery)
* – Viewer (a lib usada no bundle; pode ser importada ou estar em window.Viewer)
*
* Estrutura esperada no HTML:
* .nwe-wp-gallery
* .nwe-wp-gallery-img img (imagem principal)
* .nwe-wp-gallery-cont-list
* .nwe-wp-gallery-arrow.left/.right (setas)
* .nwe-wp-gallery-list (container com scroll horizontal)
* .nwe-wp-gallery-list-item (thumb)
* data-original=”URL” (imagem grande)
* data-pos=”1″ (posição para o contador)
* .page span (contador/posição)
*/
(function (global) {
const DEFAULTS = {
selector: “.nwe-wp-gallery”,
viewerOptions: { title: true, url: “src” },
animation: {
scrollMs: 200,
fadeMs: 200,
arrowFadeInMs: 300,
scrollPadding: 10,
scrollMultiplier: 2,
},
};
function getJquery($) {
const jq = $ || global.jQuery;
if (!jq) {
throw new Error(“[nwe-wp-gallery] jQuery não encontrado (window.jQuery).”);
}
return jq;
}
function getViewer(ViewerClass) {
// No bundle ele aparece como “new y.a(…)”.
// Aqui aceitamos via injeção ou via global window.Viewer.
return ViewerClass || global.Viewer;
}
/**
* Liga os eventos e o comportamento do “thumb strip” + setas.
* @param {jQuery} $gallery – container .nwe-wp-gallery
* @param {object} opts
*/
function bindGalleryControls($gallery, opts) {
const $ = $gallery.constructor; // jQuery ref
const $list = $gallery.find(“.nwe-wp-gallery-list”);
// Clique nas setas para scroll horizontal
$gallery
.find(“.nwe-wp-gallery-cont-list .nwe-wp-gallery-arrow”)
.off(“click.nweGallery”)
.on(“click.nweGallery”, function () {
const itemWidth = $list.find(“.nwe-wp-gallery-list-item”).outerWidth();
const step = opts.animation.scrollMultiplier * itemWidth;
let next = $list[0].scrollLeft + step + opts.animation.scrollPadding;
if ($(this).hasClass(“left”)) {
next = $list[0].scrollLeft – step – opts.animation.scrollPadding;
}
$list.animate({ scrollLeft: next }, opts.animation.scrollMs);
});
const $items = $gallery.find(“.nwe-wp-gallery-list .nwe-wp-gallery-list-item”);
// Mostra as setas quando o usuário scrolla a lista
$list
.off(“scroll.nweGallery”)
.on(“scroll.nweGallery”, function () {
const $arrows = $(this).parent().find(“.nwe-wp-gallery-arrow”);
if ($arrows.is(“:visible”) === false) {
$arrows.fadeIn(opts.animation.arrowFadeInMs);
}
});
// Força um pequeno scroll inicial (como no bundle)
$list.scrollLeft(1);
// Clique em um thumb: ativa, troca imagem principal, atualiza contador
$items
.off(“click.nweGallery”)
.on(“click.nweGallery”, function () {
$items.removeClass(“active”);
$(this).addClass(“active”);
const $main = $gallery.find(“.nwe-wp-gallery-img”);
const data = this.dataset || {};
const original = data.original;
const pos = data.pos;
if (!original) return;
const $caption = $main.find(“span”);
const $img = $main.find(“img”);
$img.fadeOut(opts.animation.fadeMs, () => {
$img.attr(“src”, original);
$caption.html(data.caption);
$img.fadeIn(opts.animation.fadeMs);
});
if (pos != null) {
$gallery.find(“.page span”).html(pos);
}
});
}
/**
* Inicializa UMA galeria: Viewer + controles.
* @param {Element|jQuery} galleryEl
* @param {object} options
* @returns {void}
*/
function initSingleGallery(galleryEl, options = {}) {
const opts = mergeDeep({}, DEFAULTS, options);
const $ = getJquery(opts.$);
const ViewerClass = getViewer(opts.Viewer);
const $gallery = $(galleryEl);
if ($gallery.length === 0) return;
// 1) Viewer (clique na imagem e abre lightbox)
if (ViewerClass) {
// Evita duplicar Viewer caso você reinicialize via AJAX/hook
// (a lib geralmente seta “element.viewer”, mas isso depende da versão).
try {
// eslint-disable-next-line no-new
new ViewerClass($gallery[0], opts.viewerOptions);
} catch (e) {
// Se o Viewer não estiver disponível/compatível, segue só com os controles
// para não quebrar a página.
}
}
// 2) Controles (setas + thumbs)
bindGalleryControls($gallery, opts);
}
/**
* Inicializa TODAS as galerias que existem no DOM.
* @param {object} options
*/
function initAllGalleries(options = {}) {
const opts = mergeDeep({}, DEFAULTS, options);
const $ = getJquery(opts.$);
$(opts.selector).each(function () {
initSingleGallery(this, opts);
});
}
/**
* Reproduz o comportamento do bundle:
* – Ao DOMContentLoaded inicializa tudo
* – Se existir wp.hooks, registra o addAction para reinicializar galerias inseridas dinamicamente
*/
function bootstrapNweWpGallery(options = {}) {
const opts = mergeDeep({}, DEFAULTS, options);
global.addEventListener(“DOMContentLoaded”, function () {
initAllGalleries(opts);
});
// Hook usado no bundle: “nwe_next_post_after_insert”
if (global.wp && global.wp.hooks && typeof global.wp.hooks.addAction === “function”) {
global.wp.hooks.addAction(
“nwe_next_post_after_insert”,
“theme_next_post_after_insert”,
(containerEl) => {
if (!containerEl) return;
const galleries = containerEl.querySelectorAll(opts.selector);
if (!galleries || galleries.length === 0) return;
galleries.forEach((el) => initSingleGallery(el, opts));
}
);
}
}
// Helpers simples (sem depender de libs)
function isObject(item) {
return item && typeof item === “object” && !Array.isArray(item);
}
function mergeDeep(target, …sources) {
if (!sources.length) return target;
const source = sources.shift();
if (isObject(target) && isObject(source)) {
for (const key in source) {
if (isObject(source[key])) {
if (!target[key]) Object.assign(target, { [key]: {} });
mergeDeep(target[key], source[key]);
} else {
Object.assign(target, { [key]: source[key] });
}
}
}
return mergeDeep(target, …sources);
}
// Exports globais (pode trocar para export default se estiver em bundler)
global.NweWpGallery = {
initSingleGallery,
initAllGalleries,
bootstrapNweWpGallery,
};
})(window);
window.NweWpGallery.bootstrapNweWpGallery();
Aos 93 anos, esse patrimônio continua espalhado por uma geografia afetiva: Lago das Rosas, Bosque dos Buritis, Areião, Vaca Brava, Parque Flamboyant, Jardim Botânico. Também vive na praça do bairro, na mata menos visitada e no exemplar que identifica uma rua melhor que sua placa. Quem mora aqui sabe: uma conversa sobre Goiânia frequentemente começa com “naquele tempo havia uma árvore”, mas convém prestar atenção ao tempo verbal.
/**
* nwe-wp-gallery.js
*
* Extraído do bundle (public.js) para uso em arquivo separado.
* Requer:
* – jQuery (window.jQuery)
* – Viewer (a lib usada no bundle; pode ser importada ou estar em window.Viewer)
*
* Estrutura esperada no HTML:
* .nwe-wp-gallery
* .nwe-wp-gallery-img img (imagem principal)
* .nwe-wp-gallery-cont-list
* .nwe-wp-gallery-arrow.left/.right (setas)
* .nwe-wp-gallery-list (container com scroll horizontal)
* .nwe-wp-gallery-list-item (thumb)
* data-original=”URL” (imagem grande)
* data-pos=”1″ (posição para o contador)
* .page span (contador/posição)
*/
(function (global) {
const DEFAULTS = {
selector: “.nwe-wp-gallery”,
viewerOptions: { title: true, url: “src” },
animation: {
scrollMs: 200,
fadeMs: 200,
arrowFadeInMs: 300,
scrollPadding: 10,
scrollMultiplier: 2,
},
};
function getJquery($) {
const jq = $ || global.jQuery;
if (!jq) {
throw new Error(“[nwe-wp-gallery] jQuery não encontrado (window.jQuery).”);
}
return jq;
}
function getViewer(ViewerClass) {
// No bundle ele aparece como “new y.a(…)”.
// Aqui aceitamos via injeção ou via global window.Viewer.
return ViewerClass || global.Viewer;
}
/**
* Liga os eventos e o comportamento do “thumb strip” + setas.
* @param {jQuery} $gallery – container .nwe-wp-gallery
* @param {object} opts
*/
function bindGalleryControls($gallery, opts) {
const $ = $gallery.constructor; // jQuery ref
const $list = $gallery.find(“.nwe-wp-gallery-list”);
// Clique nas setas para scroll horizontal
$gallery
.find(“.nwe-wp-gallery-cont-list .nwe-wp-gallery-arrow”)
.off(“click.nweGallery”)
.on(“click.nweGallery”, function () {
const itemWidth = $list.find(“.nwe-wp-gallery-list-item”).outerWidth();
const step = opts.animation.scrollMultiplier * itemWidth;
let next = $list[0].scrollLeft + step + opts.animation.scrollPadding;
if ($(this).hasClass(“left”)) {
next = $list[0].scrollLeft – step – opts.animation.scrollPadding;
}
$list.animate({ scrollLeft: next }, opts.animation.scrollMs);
});
const $items = $gallery.find(“.nwe-wp-gallery-list .nwe-wp-gallery-list-item”);
// Mostra as setas quando o usuário scrolla a lista
$list
.off(“scroll.nweGallery”)
.on(“scroll.nweGallery”, function () {
const $arrows = $(this).parent().find(“.nwe-wp-gallery-arrow”);
if ($arrows.is(“:visible”) === false) {
$arrows.fadeIn(opts.animation.arrowFadeInMs);
}
});
// Força um pequeno scroll inicial (como no bundle)
$list.scrollLeft(1);
// Clique em um thumb: ativa, troca imagem principal, atualiza contador
$items
.off(“click.nweGallery”)
.on(“click.nweGallery”, function () {
$items.removeClass(“active”);
$(this).addClass(“active”);
const $main = $gallery.find(“.nwe-wp-gallery-img”);
const data = this.dataset || {};
const original = data.original;
const pos = data.pos;
if (!original) return;
const $caption = $main.find(“span”);
const $img = $main.find(“img”);
$img.fadeOut(opts.animation.fadeMs, () => {
$img.attr(“src”, original);
$caption.html(data.caption);
$img.fadeIn(opts.animation.fadeMs);
});
if (pos != null) {
$gallery.find(“.page span”).html(pos);
}
});
}
/**
* Inicializa UMA galeria: Viewer + controles.
* @param {Element|jQuery} galleryEl
* @param {object} options
* @returns {void}
*/
function initSingleGallery(galleryEl, options = {}) {
const opts = mergeDeep({}, DEFAULTS, options);
const $ = getJquery(opts.$);
const ViewerClass = getViewer(opts.Viewer);
const $gallery = $(galleryEl);
if ($gallery.length === 0) return;
// 1) Viewer (clique na imagem e abre lightbox)
if (ViewerClass) {
// Evita duplicar Viewer caso você reinicialize via AJAX/hook
// (a lib geralmente seta “element.viewer”, mas isso depende da versão).
try {
// eslint-disable-next-line no-new
new ViewerClass($gallery[0], opts.viewerOptions);
} catch (e) {
// Se o Viewer não estiver disponível/compatível, segue só com os controles
// para não quebrar a página.
}
}
// 2) Controles (setas + thumbs)
bindGalleryControls($gallery, opts);
}
/**
* Inicializa TODAS as galerias que existem no DOM.
* @param {object} options
*/
function initAllGalleries(options = {}) {
const opts = mergeDeep({}, DEFAULTS, options);
const $ = getJquery(opts.$);
$(opts.selector).each(function () {
initSingleGallery(this, opts);
});
}
/**
* Reproduz o comportamento do bundle:
* – Ao DOMContentLoaded inicializa tudo
* – Se existir wp.hooks, registra o addAction para reinicializar galerias inseridas dinamicamente
*/
function bootstrapNweWpGallery(options = {}) {
const opts = mergeDeep({}, DEFAULTS, options);
global.addEventListener(“DOMContentLoaded”, function () {
initAllGalleries(opts);
});
// Hook usado no bundle: “nwe_next_post_after_insert”
if (global.wp && global.wp.hooks && typeof global.wp.hooks.addAction === “function”) {
global.wp.hooks.addAction(
“nwe_next_post_after_insert”,
“theme_next_post_after_insert”,
(containerEl) => {
if (!containerEl) return;
const galleries = containerEl.querySelectorAll(opts.selector);
if (!galleries || galleries.length === 0) return;
galleries.forEach((el) => initSingleGallery(el, opts));
}
);
}
}
// Helpers simples (sem depender de libs)
function isObject(item) {
return item && typeof item === “object” && !Array.isArray(item);
}
function mergeDeep(target, …sources) {
if (!sources.length) return target;
const source = sources.shift();
if (isObject(target) && isObject(source)) {
for (const key in source) {
if (isObject(source[key])) {
if (!target[key]) Object.assign(target, { [key]: {} });
mergeDeep(target[key], source[key]);
} else {
Object.assign(target, { [key]: source[key] });
}
}
}
return mergeDeep(target, …sources);
}
// Exports globais (pode trocar para export default se estiver em bundler)
global.NweWpGallery = {
initSingleGallery,
initAllGalleries,
bootstrapNweWpGallery,
};
})(window);
window.NweWpGallery.bootstrapNweWpGallery();
Antes de receber o desenho das avenidas, o território já tinha o trabalho das águas. O Cerrado protegia o chão, favorecia a infiltração e moderava o escoamento. A cidade cresceu alterando esse funcionamento e passou a contratar obras para tentar realizar parte do serviço que raízes, folhas e solo faziam sem apresentar orçamento.
O Lago das Rosas guarda um capítulo dessa infância. Ali foi criado o Horto Florestal, em 1937; o zoológico seria oficialmente fundado em 1956. A placa de inauguração do lago data de 1940, e seu nome veio de um jardim de rosas anterior à obra. Entre muretas e trampolim no estilo art déco (a plataforma, reconhecida como única no mundo, foi usada inúmeras vezes para competições de saltos ornamentais ainda nos anos 1930) onde natureza e arquitetura aprenderam a envelhecer juntas. Seria bom que recebessem juntas o cuidado devido.
/**
* nwe-wp-gallery.js
*
* Extraído do bundle (public.js) para uso em arquivo separado.
* Requer:
* – jQuery (window.jQuery)
* – Viewer (a lib usada no bundle; pode ser importada ou estar em window.Viewer)
*
* Estrutura esperada no HTML:
* .nwe-wp-gallery
* .nwe-wp-gallery-img img (imagem principal)
* .nwe-wp-gallery-cont-list
* .nwe-wp-gallery-arrow.left/.right (setas)
* .nwe-wp-gallery-list (container com scroll horizontal)
* .nwe-wp-gallery-list-item (thumb)
* data-original=”URL” (imagem grande)
* data-pos=”1″ (posição para o contador)
* .page span (contador/posição)
*/
(function (global) {
const DEFAULTS = {
selector: “.nwe-wp-gallery”,
viewerOptions: { title: true, url: “src” },
animation: {
scrollMs: 200,
fadeMs: 200,
arrowFadeInMs: 300,
scrollPadding: 10,
scrollMultiplier: 2,
},
};
function getJquery($) {
const jq = $ || global.jQuery;
if (!jq) {
throw new Error(“[nwe-wp-gallery] jQuery não encontrado (window.jQuery).”);
}
return jq;
}
function getViewer(ViewerClass) {
// No bundle ele aparece como “new y.a(…)”.
// Aqui aceitamos via injeção ou via global window.Viewer.
return ViewerClass || global.Viewer;
}
/**
* Liga os eventos e o comportamento do “thumb strip” + setas.
* @param {jQuery} $gallery – container .nwe-wp-gallery
* @param {object} opts
*/
function bindGalleryControls($gallery, opts) {
const $ = $gallery.constructor; // jQuery ref
const $list = $gallery.find(“.nwe-wp-gallery-list”);
// Clique nas setas para scroll horizontal
$gallery
.find(“.nwe-wp-gallery-cont-list .nwe-wp-gallery-arrow”)
.off(“click.nweGallery”)
.on(“click.nweGallery”, function () {
const itemWidth = $list.find(“.nwe-wp-gallery-list-item”).outerWidth();
const step = opts.animation.scrollMultiplier * itemWidth;
let next = $list[0].scrollLeft + step + opts.animation.scrollPadding;
if ($(this).hasClass(“left”)) {
next = $list[0].scrollLeft – step – opts.animation.scrollPadding;
}
$list.animate({ scrollLeft: next }, opts.animation.scrollMs);
});
const $items = $gallery.find(“.nwe-wp-gallery-list .nwe-wp-gallery-list-item”);
// Mostra as setas quando o usuário scrolla a lista
$list
.off(“scroll.nweGallery”)
.on(“scroll.nweGallery”, function () {
const $arrows = $(this).parent().find(“.nwe-wp-gallery-arrow”);
if ($arrows.is(“:visible”) === false) {
$arrows.fadeIn(opts.animation.arrowFadeInMs);
}
});
// Força um pequeno scroll inicial (como no bundle)
$list.scrollLeft(1);
// Clique em um thumb: ativa, troca imagem principal, atualiza contador
$items
.off(“click.nweGallery”)
.on(“click.nweGallery”, function () {
$items.removeClass(“active”);
$(this).addClass(“active”);
const $main = $gallery.find(“.nwe-wp-gallery-img”);
const data = this.dataset || {};
const original = data.original;
const pos = data.pos;
if (!original) return;
const $caption = $main.find(“span”);
const $img = $main.find(“img”);
$img.fadeOut(opts.animation.fadeMs, () => {
$img.attr(“src”, original);
$caption.html(data.caption);
$img.fadeIn(opts.animation.fadeMs);
});
if (pos != null) {
$gallery.find(“.page span”).html(pos);
}
});
}
/**
* Inicializa UMA galeria: Viewer + controles.
* @param {Element|jQuery} galleryEl
* @param {object} options
* @returns {void}
*/
function initSingleGallery(galleryEl, options = {}) {
const opts = mergeDeep({}, DEFAULTS, options);
const $ = getJquery(opts.$);
const ViewerClass = getViewer(opts.Viewer);
const $gallery = $(galleryEl);
if ($gallery.length === 0) return;
// 1) Viewer (clique na imagem e abre lightbox)
if (ViewerClass) {
// Evita duplicar Viewer caso você reinicialize via AJAX/hook
// (a lib geralmente seta “element.viewer”, mas isso depende da versão).
try {
// eslint-disable-next-line no-new
new ViewerClass($gallery[0], opts.viewerOptions);
} catch (e) {
// Se o Viewer não estiver disponível/compatível, segue só com os controles
// para não quebrar a página.
}
}
// 2) Controles (setas + thumbs)
bindGalleryControls($gallery, opts);
}
/**
* Inicializa TODAS as galerias que existem no DOM.
* @param {object} options
*/
function initAllGalleries(options = {}) {
const opts = mergeDeep({}, DEFAULTS, options);
const $ = getJquery(opts.$);
$(opts.selector).each(function () {
initSingleGallery(this, opts);
});
}
/**
* Reproduz o comportamento do bundle:
* – Ao DOMContentLoaded inicializa tudo
* – Se existir wp.hooks, registra o addAction para reinicializar galerias inseridas dinamicamente
*/
function bootstrapNweWpGallery(options = {}) {
const opts = mergeDeep({}, DEFAULTS, options);
global.addEventListener(“DOMContentLoaded”, function () {
initAllGalleries(opts);
});
// Hook usado no bundle: “nwe_next_post_after_insert”
if (global.wp && global.wp.hooks && typeof global.wp.hooks.addAction === “function”) {
global.wp.hooks.addAction(
“nwe_next_post_after_insert”,
“theme_next_post_after_insert”,
(containerEl) => {
if (!containerEl) return;
const galleries = containerEl.querySelectorAll(opts.selector);
if (!galleries || galleries.length === 0) return;
galleries.forEach((el) => initSingleGallery(el, opts));
}
);
}
}
// Helpers simples (sem depender de libs)
function isObject(item) {
return item && typeof item === “object” && !Array.isArray(item);
}
function mergeDeep(target, …sources) {
if (!sources.length) return target;
const source = sources.shift();
if (isObject(target) && isObject(source)) {
for (const key in source) {
if (isObject(source[key])) {
if (!target[key]) Object.assign(target, { [key]: {} });
mergeDeep(target[key], source[key]);
} else {
Object.assign(target, { [key]: source[key] });
}
}
}
return mergeDeep(target, …sources);
}
// Exports globais (pode trocar para export default se estiver em bundler)
global.NweWpGallery = {
initSingleGallery,
initAllGalleries,
bootstrapNweWpGallery,
};
})(window);
window.NweWpGallery.bootstrapNweWpGallery();
Outros jardins ficaram sobretudo na memória. O Plano Diretor de Arborização recupera os fícus da Praça Cívica e da Avenida Goiás e os flamboyants da Araguaia e da Tocantins. Pioneiros descrevem calçadas cobertas de pétalas e copas que faziam do caminho uma estação do ano. A cidade podia ser reconhecida por suas floradas.

Essa continuidade se perdeu. O conhecimento atual permite escolher espécies mais adequadas, valorizar as nativas e corrigir erros antigos, inclusive o pouco apreço que se tinha pelo próprio Cerrado. A lembrança das avenidas floridas oferece uma exigência à cidade de hoje: conhecer mais deveria resultar em viver melhor.
Na Praça Cívica e na Avenida Goiás, obras do BRT também alteraram a arborização. Em 2021, o Iphan condicionou sua autorização na praça à recomposição da massa vegetativa retirada para as estações. Em 2025, outras remoções, junto ao Antigo Fórum, foram justificadas pela Secult para proteção das fundações e drenagem da própria praça, com recomposição anunciada.

Cada intervenção tem sua história, mas a promessa de reposição precisa ter acompanhamento. Uma muda carrega futuro. Uma árvore adulta já entrega benefícios (vale notar a presença de várias espécies de pássaros na cidade; o motivo são as árvores. Nestas há vida: espaço para ninhos, insetos e, às vezes, frutos para a alimentação). O intervalo entre ambas não desaparece num termo de compensação.
No Jóquei Clube, a troca foi mais prosaica. O conjunto de Paulo Mendes da Rocha (arquiteto de grandeza internacional) articulava arquitetura e um bosque associado ao córrego dos Buritis. Pesquisadores documentaram seu desmatamento e pavimentação; a antiga área verde virou estacionamento.
A convivência ganhou concorrência, e os carros chegaram com melhores condições de negociação (desde Juscelino Kubitschek os automóveis e caminhões se tornaram dominantes nas ruas). O bosque se foi, assim como o tradicional clube que, hoje, apodrece, em meio ao Centro tão esquecido e abandonado.

Nem os jardins que compunham o cenário com o bosque, atribuídos a Burle Marx, foram preservados. Sua passagem pela discussão ambiental da capital está registrada: em 1977, veio prestar consultoria, visitou parques, a Avenida Goiás e criticou a perda de árvores do Bosque Botafogo. Algumas advertências envelhecem porque passam tempo demais esperando providências.
Goiânia tem quem se recuse a desistir dessa conversa. Espécie de Oscar Niemeyer de saia, a talentosa e criativa Narcisa Abreu Cordeiro dedica mais de cinco décadas à arquitetura, ao urbanismo, à pesquisa histórica e à defesa das áreas verdes. Formada em 1974, com estudos também em Botânica, ajudou a projetar partes da capital e a recuperar, em livros, os fundamentos de seu planejamento. Conhece tanto a cidade construída quanto as ideias que ficaram pelo caminho.

Com Jacira Rosa Pires, desenvolveu o Goiânia Cidade Vida Verde, que fundamentou o projeto apresentado à Câmara pelo vereador Anselmo Pereira, neste ano. Recuperação ambiental, proteção das águas, valorização do Cerrado e educação pertencem à proposta; o Caminho Escola, também levado ao Legislativo, aproxima estudantes dos parques e do patrimônio. Há uma inteligência simples nessa ligação: a criança que conhece uma nascente tem mais razões para defendê-la quando crescer.

As duas também participaram da publicação sobre Amália Hermano Teixeira, professora, escritora e estudiosa da flora homenageada no Jardim Botânico. Seu interesse pelas orquídeas e pela educação aproximava conhecimento e cuidado antes que a ecologia ganhasse espaço nas solenidades. Inaugurado em 1978, o jardim abriga árvores de grande porte e nascentes do Botafogo. O nome no portão merece ser apresentado a quem passa por ele.

No Vaca Brava, a homenagem ao promotor de justiça Sulivan Silvestre (faleceu jovem, num acidente de avião), referência do Ministério Público na defesa ambiental, lembra as mobilizações pela preservação da área. No Areião, o jornalista e ambientalista Washington Novaes empresta o nome desde 2021 e deixa uma cobrança bem maior que a placa: ouvir o que passou a vida dizendo. A partir de Goiânia, onde escolheu morar, levou o Cerrado ao debate nacional. Em 2017, chamou-o de “o primo pobre dos biomas brasileiros”. Em sua propriedade, árvores plantadas por ele cresciam junto dos argumentos.

Houve também quem ensinasse a cidade a se reconhecer pela literatura. Bariani Ortêncio fez do Bosque dos Buritis parte de sua rotina; em 2026, ganhou ali uma trilha ambiental. Carmo Bernardes (sabia o nome praticamente de todas as árvores) reuniu Cerrado, bichos, rios e pessoas em sua obra que, segundo registro da UFG, já em 1945 alertava sobre erosão, assoreamento e matas ciliares. O assunto é antigo. Nossa capacidade de tratá-lo como novidade continua impressionante.
/**
* nwe-wp-gallery.js
*
* Extraído do bundle (public.js) para uso em arquivo separado.
* Requer:
* – jQuery (window.jQuery)
* – Viewer (a lib usada no bundle; pode ser importada ou estar em window.Viewer)
*
* Estrutura esperada no HTML:
* .nwe-wp-gallery
* .nwe-wp-gallery-img img (imagem principal)
* .nwe-wp-gallery-cont-list
* .nwe-wp-gallery-arrow.left/.right (setas)
* .nwe-wp-gallery-list (container com scroll horizontal)
* .nwe-wp-gallery-list-item (thumb)
* data-original=”URL” (imagem grande)
* data-pos=”1″ (posição para o contador)
* .page span (contador/posição)
*/
(function (global) {
const DEFAULTS = {
selector: “.nwe-wp-gallery”,
viewerOptions: { title: true, url: “src” },
animation: {
scrollMs: 200,
fadeMs: 200,
arrowFadeInMs: 300,
scrollPadding: 10,
scrollMultiplier: 2,
},
};
function getJquery($) {
const jq = $ || global.jQuery;
if (!jq) {
throw new Error(“[nwe-wp-gallery] jQuery não encontrado (window.jQuery).”);
}
return jq;
}
function getViewer(ViewerClass) {
// No bundle ele aparece como “new y.a(…)”.
// Aqui aceitamos via injeção ou via global window.Viewer.
return ViewerClass || global.Viewer;
}
/**
* Liga os eventos e o comportamento do “thumb strip” + setas.
* @param {jQuery} $gallery – container .nwe-wp-gallery
* @param {object} opts
*/
function bindGalleryControls($gallery, opts) {
const $ = $gallery.constructor; // jQuery ref
const $list = $gallery.find(“.nwe-wp-gallery-list”);
// Clique nas setas para scroll horizontal
$gallery
.find(“.nwe-wp-gallery-cont-list .nwe-wp-gallery-arrow”)
.off(“click.nweGallery”)
.on(“click.nweGallery”, function () {
const itemWidth = $list.find(“.nwe-wp-gallery-list-item”).outerWidth();
const step = opts.animation.scrollMultiplier * itemWidth;
let next = $list[0].scrollLeft + step + opts.animation.scrollPadding;
if ($(this).hasClass(“left”)) {
next = $list[0].scrollLeft – step – opts.animation.scrollPadding;
}
$list.animate({ scrollLeft: next }, opts.animation.scrollMs);
});
const $items = $gallery.find(“.nwe-wp-gallery-list .nwe-wp-gallery-list-item”);
// Mostra as setas quando o usuário scrolla a lista
$list
.off(“scroll.nweGallery”)
.on(“scroll.nweGallery”, function () {
const $arrows = $(this).parent().find(“.nwe-wp-gallery-arrow”);
if ($arrows.is(“:visible”) === false) {
$arrows.fadeIn(opts.animation.arrowFadeInMs);
}
});
// Força um pequeno scroll inicial (como no bundle)
$list.scrollLeft(1);
// Clique em um thumb: ativa, troca imagem principal, atualiza contador
$items
.off(“click.nweGallery”)
.on(“click.nweGallery”, function () {
$items.removeClass(“active”);
$(this).addClass(“active”);
const $main = $gallery.find(“.nwe-wp-gallery-img”);
const data = this.dataset || {};
const original = data.original;
const pos = data.pos;
if (!original) return;
const $caption = $main.find(“span”);
const $img = $main.find(“img”);
$img.fadeOut(opts.animation.fadeMs, () => {
$img.attr(“src”, original);
$caption.html(data.caption);
$img.fadeIn(opts.animation.fadeMs);
});
if (pos != null) {
$gallery.find(“.page span”).html(pos);
}
});
}
/**
* Inicializa UMA galeria: Viewer + controles.
* @param {Element|jQuery} galleryEl
* @param {object} options
* @returns {void}
*/
function initSingleGallery(galleryEl, options = {}) {
const opts = mergeDeep({}, DEFAULTS, options);
const $ = getJquery(opts.$);
const ViewerClass = getViewer(opts.Viewer);
const $gallery = $(galleryEl);
if ($gallery.length === 0) return;
// 1) Viewer (clique na imagem e abre lightbox)
if (ViewerClass) {
// Evita duplicar Viewer caso você reinicialize via AJAX/hook
// (a lib geralmente seta “element.viewer”, mas isso depende da versão).
try {
// eslint-disable-next-line no-new
new ViewerClass($gallery[0], opts.viewerOptions);
} catch (e) {
// Se o Viewer não estiver disponível/compatível, segue só com os controles
// para não quebrar a página.
}
}
// 2) Controles (setas + thumbs)
bindGalleryControls($gallery, opts);
}
/**
* Inicializa TODAS as galerias que existem no DOM.
* @param {object} options
*/
function initAllGalleries(options = {}) {
const opts = mergeDeep({}, DEFAULTS, options);
const $ = getJquery(opts.$);
$(opts.selector).each(function () {
initSingleGallery(this, opts);
});
}
/**
* Reproduz o comportamento do bundle:
* – Ao DOMContentLoaded inicializa tudo
* – Se existir wp.hooks, registra o addAction para reinicializar galerias inseridas dinamicamente
*/
function bootstrapNweWpGallery(options = {}) {
const opts = mergeDeep({}, DEFAULTS, options);
global.addEventListener(“DOMContentLoaded”, function () {
initAllGalleries(opts);
});
// Hook usado no bundle: “nwe_next_post_after_insert”
if (global.wp && global.wp.hooks && typeof global.wp.hooks.addAction === “function”) {
global.wp.hooks.addAction(
“nwe_next_post_after_insert”,
“theme_next_post_after_insert”,
(containerEl) => {
if (!containerEl) return;
const galleries = containerEl.querySelectorAll(opts.selector);
if (!galleries || galleries.length === 0) return;
galleries.forEach((el) => initSingleGallery(el, opts));
}
);
}
}
// Helpers simples (sem depender de libs)
function isObject(item) {
return item && typeof item === “object” && !Array.isArray(item);
}
function mergeDeep(target, …sources) {
if (!sources.length) return target;
const source = sources.shift();
if (isObject(target) && isObject(source)) {
for (const key in source) {
if (isObject(source[key])) {
if (!target[key]) Object.assign(target, { [key]: {} });
mergeDeep(target[key], source[key]);
} else {
Object.assign(target, { [key]: source[key] });
}
}
}
return mergeDeep(target, …sources);
}
// Exports globais (pode trocar para export default se estiver em bundler)
global.NweWpGallery = {
initSingleGallery,
initAllGalleries,
bootstrapNweWpGallery,
};
})(window);
window.NweWpGallery.bootstrapNweWpGallery();
Bernardo Élis, eleito para a Academia Brasileira de Letras em 1975, deixou no Poema burocrático do dia da árvore uma frase que ainda trabalha e, sim, grita: “O brasileiro é antes de tudo um forte fazedor de desertos”. A jornalista, contista e poeta Eloí Calage, em “Goiânia 60 Anos: um Passeio Pela História e Goiânia – Um Mais Um Três Amigos”, ajudou diferentes leitores a conhecer a capital. Entre a ironia de um e a memória reunida pela outra, aprendemos que gostar de uma cidade também exige saber do que ela é feita. E Goiânia é feita de águas que precisam de mata.

O Parque Estadual Altamiro de Moura Pacheco, criado em 1992 e batizado em homenagem ao antigo proprietário das terras adquiridas pelo Estado, protege remanescentes florestais (fica na margem da rodovia BR-153). Com o Parque Estadual do João Leite, participa da proteção do reservatório que abastece a Grande Goiânia. Ali, a importância da floresta chega à torneira, embora raramente receba a atenção dedicada à conta. (Por lá, além das árvores, algumas bem altas, há centenas de passados.)

Na região do Jaó, a área da represa conserva mata ciliar associada ao Rio Meia Ponte; no Santa Genoveva, o Bosque do Café guarda árvores de grande porte. O principal rio da cidade, entretanto, recebe uma herança menos generosa: assoreamento, esgoto, lixo, ocupações irregulares e desmatamento das margens; problemas identificados em expedições com pesquisadores da UFG e do IFG. Goiânia apresenta seus lagos aos visitantes. Poderia ambicionar apresentar também seu rio, sem começar pelas explicações.
As pracinhas do Setor Sul contam outro desencontro. No desenho incorporado por Armando de Godoy, jardins internos aproximariam casas e percursos de pedestres. A ocupação voltou as entradas para as ruas e deixou parte desses espaços nos fundos. O automóvel ficou com a apresentação da casa; o jardim recebeu as costas. Recuperar esse conjunto permite aproveitar uma riqueza que outras cidades precisam procurar onde criar.

Há novas possibilidades em implantação. Depois de desapropriações e reflorestamento, o Morro da Serrinha atravessa outra etapa de seu parque urbano. Em outubro, o Estado anunciou investimento de R$ 14,4 milhões e entrega em 12 meses. Na Vila Rosa, onde nasce o córrego Cascavel, a preservação exige persistência: a lei de criação do parque é de 1996; a degradação da nascente motivou procedimentos do MP desde 2004 e ação judicial em 2012. A inauguração dura uma manhã inteira, mas o cuidado deve atravessar gerações.
Parte dessa geografia foi escondida. O córrego dos Buritis segue canalizado; o Botafogo perdeu trechos de mata ciliar para concreto e pistas. Impermeabilização, relevo, escoamento acelerado e limitações da drenagem ajudam a explicar as enchentes. Recuperar vegetação exige pensar a bacia inteira, além de limpar o canal. A chuva tem recebido sozinha uma responsabilidade que deveria dividir com sucessivas decisões de uso do solo.

Na superfície, algumas ausências se tornam impossíveis de ignorar. A gameleira da Araguaia com a Contorno teve retirada iniciada em abril de 2025, após incêndio; segundo a prefeitura, um laudo apontou inviabilidade de recuperação. Na Praça da Cirrose, no Setor Oeste, a disputa por quatro gameleiras levou a nova perícia do MP: em outubro, recomendou-se retirar uma por risco elevado e preservar três com manejo e monitoramento. O resultado ensina que cada árvore exige diagnóstico. Segurança e preservação dependem dessa distinção.
No Lago das Rosas, a Justiça suspendeu em maio cortes vinculados à revitalização e a um espaço para animais de estimação. Segundo o MP, a proposta abrangia 48 árvores, incluindo exemplares saudáveis cuja remoção abriria lugar para a obra. Melhorar um parque é uma boa ideia, mas recomenda-se que o projeto considere a vegetação que encontrou ali.
As podas de prestadoras da Equatorial também motivaram fiscalização do MP após denúncias de intervenções drásticas. A empresa sustenta a observância das normas. A população precisa conhecer autorizações, justificativas e responsáveis, inclusive nos serviços noturnos. Em 14 de outubro, a CCJ aprovou proposta de relatório técnico para podas de concessionárias, ainda dependente de plenário e sanção. A copa deve participar da solução de engenharia, em vez de ser tratada como erro de instalação da natureza e imediatamente decepada.
O reconhecimento Cidade Árvore do Mundo, do programa da FAO e da Arbor Day Foundation, oferece um compromisso a cumprir. A distinção considera a gestão da arborização; não significa primeiro lugar num ranking mundial. O diploma merece a celebração e as árvores precisam continuar merecendo o diploma.
O clima torna a cobrança urgente. Pesquisa de Tomás Andrés Borges Barrera, defendida na UFG em 2026, encontrou intensificação das ilhas de calor superficiais em 64% dos bairros analisados entre 2006 e 2025 em Goiânia. O boletim federal de setembro apontou ainda 95% de probabilidade de El Niño muito forte entre outubro e dezembro, com temperaturas acima da faixa normal em quase todo o país. Os efeitos locais dependem da evolução meteorológica; a preparação é que não deveria depender de surpresa.

Existem respostas em construção: manuais municipais de poda e arborização; o Plantando Árvores, Colhendo Vidas, nas escolas; pesquisas e expedições apoiadas pelo CEMPA-Cerrado; ações da Codevasf para infiltração e recuperação hídrica na bacia do Meia Ponte. No Bosque dos Buritis, um projeto contemporâneo do escritório Burle Marx, ainda sem prazo de execução anunciado, prevê integração com o Museu de Arte e soluções de drenagem.
Conhecimento existe. Cabe transformá-lo em orçamento, continuidade e resultado. Plantar é um começo; a política pública se comprova quando a árvore cresce. A responsabilidade também chega à nossa porta. A árvore da calçada precisa de espaço, a praça depende do uso respeitoso, o córrego sofre com o que moradores e empresas despejam nele. Preservar inclui acompanhar obras, pedir informações e reconhecer valor naquilo que continua vivo sem precisar de uma nova inauguração.
/**
* nwe-wp-gallery.js
*
* Extraído do bundle (public.js) para uso em arquivo separado.
* Requer:
* – jQuery (window.jQuery)
* – Viewer (a lib usada no bundle; pode ser importada ou estar em window.Viewer)
*
* Estrutura esperada no HTML:
* .nwe-wp-gallery
* .nwe-wp-gallery-img img (imagem principal)
* .nwe-wp-gallery-cont-list
* .nwe-wp-gallery-arrow.left/.right (setas)
* .nwe-wp-gallery-list (container com scroll horizontal)
* .nwe-wp-gallery-list-item (thumb)
* data-original=”URL” (imagem grande)
* data-pos=”1″ (posição para o contador)
* .page span (contador/posição)
*/
(function (global) {
const DEFAULTS = {
selector: “.nwe-wp-gallery”,
viewerOptions: { title: true, url: “src” },
animation: {
scrollMs: 200,
fadeMs: 200,
arrowFadeInMs: 300,
scrollPadding: 10,
scrollMultiplier: 2,
},
};
function getJquery($) {
const jq = $ || global.jQuery;
if (!jq) {
throw new Error(“[nwe-wp-gallery] jQuery não encontrado (window.jQuery).”);
}
return jq;
}
function getViewer(ViewerClass) {
// No bundle ele aparece como “new y.a(…)”.
// Aqui aceitamos via injeção ou via global window.Viewer.
return ViewerClass || global.Viewer;
}
/**
* Liga os eventos e o comportamento do “thumb strip” + setas.
* @param {jQuery} $gallery – container .nwe-wp-gallery
* @param {object} opts
*/
function bindGalleryControls($gallery, opts) {
const $ = $gallery.constructor; // jQuery ref
const $list = $gallery.find(“.nwe-wp-gallery-list”);
// Clique nas setas para scroll horizontal
$gallery
.find(“.nwe-wp-gallery-cont-list .nwe-wp-gallery-arrow”)
.off(“click.nweGallery”)
.on(“click.nweGallery”, function () {
const itemWidth = $list.find(“.nwe-wp-gallery-list-item”).outerWidth();
const step = opts.animation.scrollMultiplier * itemWidth;
let next = $list[0].scrollLeft + step + opts.animation.scrollPadding;
if ($(this).hasClass(“left”)) {
next = $list[0].scrollLeft – step – opts.animation.scrollPadding;
}
$list.animate({ scrollLeft: next }, opts.animation.scrollMs);
});
const $items = $gallery.find(“.nwe-wp-gallery-list .nwe-wp-gallery-list-item”);
// Mostra as setas quando o usuário scrolla a lista
$list
.off(“scroll.nweGallery”)
.on(“scroll.nweGallery”, function () {
const $arrows = $(this).parent().find(“.nwe-wp-gallery-arrow”);
if ($arrows.is(“:visible”) === false) {
$arrows.fadeIn(opts.animation.arrowFadeInMs);
}
});
// Força um pequeno scroll inicial (como no bundle)
$list.scrollLeft(1);
// Clique em um thumb: ativa, troca imagem principal, atualiza contador
$items
.off(“click.nweGallery”)
.on(“click.nweGallery”, function () {
$items.removeClass(“active”);
$(this).addClass(“active”);
const $main = $gallery.find(“.nwe-wp-gallery-img”);
const data = this.dataset || {};
const original = data.original;
const pos = data.pos;
if (!original) return;
const $caption = $main.find(“span”);
const $img = $main.find(“img”);
$img.fadeOut(opts.animation.fadeMs, () => {
$img.attr(“src”, original);
$caption.html(data.caption);
$img.fadeIn(opts.animation.fadeMs);
});
if (pos != null) {
$gallery.find(“.page span”).html(pos);
}
});
}
/**
* Inicializa UMA galeria: Viewer + controles.
* @param {Element|jQuery} galleryEl
* @param {object} options
* @returns {void}
*/
function initSingleGallery(galleryEl, options = {}) {
const opts = mergeDeep({}, DEFAULTS, options);
const $ = getJquery(opts.$);
const ViewerClass = getViewer(opts.Viewer);
const $gallery = $(galleryEl);
if ($gallery.length === 0) return;
// 1) Viewer (clique na imagem e abre lightbox)
if (ViewerClass) {
// Evita duplicar Viewer caso você reinicialize via AJAX/hook
// (a lib geralmente seta “element.viewer”, mas isso depende da versão).
try {
// eslint-disable-next-line no-new
new ViewerClass($gallery[0], opts.viewerOptions);
} catch (e) {
// Se o Viewer não estiver disponível/compatível, segue só com os controles
// para não quebrar a página.
}
}
// 2) Controles (setas + thumbs)
bindGalleryControls($gallery, opts);
}
/**
* Inicializa TODAS as galerias que existem no DOM.
* @param {object} options
*/
function initAllGalleries(options = {}) {
const opts = mergeDeep({}, DEFAULTS, options);
const $ = getJquery(opts.$);
$(opts.selector).each(function () {
initSingleGallery(this, opts);
});
}
/**
* Reproduz o comportamento do bundle:
* – Ao DOMContentLoaded inicializa tudo
* – Se existir wp.hooks, registra o addAction para reinicializar galerias inseridas dinamicamente
*/
function bootstrapNweWpGallery(options = {}) {
const opts = mergeDeep({}, DEFAULTS, options);
global.addEventListener(“DOMContentLoaded”, function () {
initAllGalleries(opts);
});
// Hook usado no bundle: “nwe_next_post_after_insert”
if (global.wp && global.wp.hooks && typeof global.wp.hooks.addAction === “function”) {
global.wp.hooks.addAction(
“nwe_next_post_after_insert”,
“theme_next_post_after_insert”,
(containerEl) => {
if (!containerEl) return;
const galleries = containerEl.querySelectorAll(opts.selector);
if (!galleries || galleries.length === 0) return;
galleries.forEach((el) => initSingleGallery(el, opts));
}
);
}
}
// Helpers simples (sem depender de libs)
function isObject(item) {
return item && typeof item === “object” && !Array.isArray(item);
}
function mergeDeep(target, …sources) {
if (!sources.length) return target;
const source = sources.shift();
if (isObject(target) && isObject(source)) {
for (const key in source) {
if (isObject(source[key])) {
if (!target[key]) Object.assign(target, { [key]: {} });
mergeDeep(target[key], source[key]);
} else {
Object.assign(target, { [key]: source[key] });
}
}
}
return mergeDeep(target, …sources);
}
// Exports globais (pode trocar para export default se estiver em bundler)
global.NweWpGallery = {
initSingleGallery,
initAllGalleries,
bootstrapNweWpGallery,
};
})(window);
window.NweWpGallery.bootstrapNweWpGallery();
Aos 93 anos, Goiânia tem motivos para celebrar. Seu maior tesouro permanece vivo, capaz de ser recuperado, ampliado e compartilhado por mais bairros. Há gente que conhece seus caminhos, jardins esperando cuidado e crianças que ainda aprenderão a cidade pelo nome de uma árvore.
Começamos sob uma copa. Temos condições de chegar ao centenário com muitas outras – e com a maturidade de compreender o que elas nos oferecem. Se uma árvore abrigou o começo de Goiânia, o que estamos dispostos a fazer, como governantes e moradores, para que o verde continue abrigando o seu futuro?
Leia também:
- Goiânia, 93 anos: uma cidade, muitas histórias e algumas perguntas que não podem esperar pelo centenário
- O Centro de Goiânia não morreu. Foi abandonado à própria sorte
O post Uma cidade à altura de suas árvores apareceu primeiro em Jornal Opção.














