SWCore / Componentes / Content

Content Componentes

Busca dados JSON e renderiza numa lista usando um template HTML com {{variáveis}}.

O que é

Carrega conteúdo dinâmico (posts, produtos, comentários) de uma API e injeta na página usando um <template> — sem escrever o HTML de cada item manualmente em JS.

Como funciona

Interpola {{campo}} tanto em texto quanto em atributos do template. Suporta três gatilhos: carrega ao aparecer na página (load), ao clicar num botão (click), ou ao entrar na viewport (visible) — bom pra scroll infinito controlado.

Exemplos

1. Padrão — carrega ao aparecer (load) Ao vivo
<div sw-content="../assets/demo-posts.json">
  <template>
    <article class="demo-box demo-mb"><p class="demo-box-title">{{titulo}}</p><p class="demo-box-sub">{{resumo}}</p></article>
  </template>
</div>
2. Gatilho por clique Ao vivo
<button id="btn-carregar" type="button" class="sw-btn">Carregar posts</button>
<div sw-content="/api/posts" sw-content-trigger="click" sw-content-btn="#btn-carregar">
  <template><article>{{titulo}}</article></template>
</div>
3. Gatilho por visibilidade — role até aparecer Ao vivo

O bloco abaixo só busca o JSON quando entra na tela (IntersectionObserver) — role até ele aparecer.

<div sw-content="/api/posts" sw-content-trigger="visible">
  <template><article>{{titulo}}</article></template>
</div>
4. Estado vazio e erro — os dois reais, não simulados Ao vivo

Lista vazia (JSON real, array [])

Resposta inválida (falha real, sem 404 automático)

<div sw-content="/api/posts"
     sw-content-empty="Nenhum post publicado ainda."
     sw-content-err="Não foi possível carregar os posts.">
  <template><article>{{titulo}}</article></template>
</div>
5. Paginação automática Ao vivo

Com sw-content-paginate, o módulo injeta sozinho os botões ← Anterior/Próxima → quando a resposta traz pagina/paginas — precisa de um backend real que entenda ?page=N, por isso aqui fica só o código de referência (não dá pra simular isso com um arquivo estático).

<div sw-content="/api/posts?limit=10" sw-content-paginate>
  <template>
    <article>{{titulo}}</article>
  </template>
</div>

Formato esperado na resposta:

{
  "dados":   [ { "titulo": "Post A" } ],
  "total":   42,
  "pagina":  1,
  "paginas": 5
}
6. Template externo compartilhado Ao vivo

Bloco 1

Bloco 2 — mesmo template

<template id="card-post">
  <article>{{titulo}}</article>
</template>

<div sw-content="/api/posts?limit=3" sw-content-tmpl="#card-post"></div>
<div sw-content="/api/posts?status=A&limit=6" sw-content-tmpl="#card-post"></div>
7. API JavaScript Ao vivo
// Recarregar bloco via JS
const el = document.querySelector('[sw-content]');
SW.Content.load(el);

// Recarregar ao trocar um filtro
document.querySelector('#filtro').addEventListener('change', (e) => {
  el.setAttribute('sw-content', '/api/posts?tipo=' + e.target.value);
  SW.Content.load(el);
});

// Escutar depois de renderizar
el.addEventListener('sw:content:loaded', (e) => {
  console.log('Dados:', e.detail.dados);
});

Atributos

sw-content
URL do endpoint JSON
sw-content-tmpl
seletor do <template> (padrão: procura um <template> dentro do próprio elemento)
sw-content-trigger
"load" (padrão), "click" ou "visible"
sw-content-paginate
ativa paginação (espera pagina/paginas na resposta)
sw-content-empty / sw-content-err
mensagens pra lista vazia / erro de rede

Variantes

Nenhum.

Eventos

sw:content:loaded
{ dados }

API (JavaScript)

SW.Content.load(el)
recarrega por código

Requisitos

  • O endpoint precisa responder um array JSON (ou {dados:[...]}/{data:[...]}) — não interpreta HTML.

Limitações — o que ele não faz

  • Paginação (sw-content-paginate) precisa de um backend real que leia ?page=N — não dá pra demonstrar ao vivo com um arquivo JSON estático (por isso o exemplo 5 é só código de referência, os outros 6 são ao vivo de verdade).