Frameworks

Astro

Lee lo que publicas desde un sitio Astro con @hollware/astro, al pedir la página o al compilar, y renderízalo con tus propios componentes de Astro.

Astro

@hollware/astro le da a la content layer de Astro dos loaders, y dos componentes que renderizan lo que cargan.

npm install @hollware/astro

Leer al pedir la página

Una live collection lee en cada solicitud, así que lo que publicas aparece en la siguiente, sin recompilar. En Cloudflare, vincula tu Worker de Hollware en el wrangler.jsonc del sitio:

"services": [{ "binding": "HOLLWARE", "service": "my-cms", "entrypoint": "Hollware" }]
// src/live.config.ts
import { env } from 'cloudflare:workers'
import { defineLiveCollection } from 'astro/content/config'
import { hollwareBinding, hollwareLiveLoader } from '@hollware/astro'

const blog = defineLiveCollection({
  loader: hollwareLiveLoader({
    site: 'my-site',
    collection: 'blog',
    locale: 'es',
    reader: () => hollwareBinding(env.HOLLWARE),
  }),
})
export const collections = { blog }

Haz una colección por locale. El id de una entrada es su slug y su data el frontmatter, con los campos que llena Hollware ya llenos.

Leer al compilar

Para un sitio estático, hollwareLoader en src/content.config.ts lee una vez cada entrada publicada, al compilar, por HTTP con un token de lectura (npx hollware token create --read):

// src/content.config.ts
import { defineCollection } from 'astro:content'
import { hollwareLoader } from '@hollware/astro'

const blog = defineCollection({
  loader: hollwareLoader({
    site: 'my-site',
    collection: 'blog',
    locale: 'es',
    url: 'https://cms.example.com',
    token: process.env.HOLLWARE_TOKEN ?? '',
  }),
})
export const collections = { blog }

Dale a defineCollection un schema para validar el frontmatter, como con cualquier loader.

Renderiza una entrada

---
import HollwareContent from '@hollware/astro/HollwareContent.astro'
import HollwareImage from '@hollware/astro/HollwareImage.astro'
import { getLiveEntry } from 'astro:content'
import Callout from '../components/Callout.astro'

const { entry } = await getLiveEntry('blog', Astro.params.slug!)
if (!entry) return new Response('Not found', { status: 404 })
---

<h1>{entry.data.title}</h1>
<HollwareImage entry={entry} field="img" />
<HollwareContent entry={entry} components={{ callout: Callout }} />
  • HollwareContent.astro renderiza la entrada desde su documento, con tus propios componentes de Astro para los componentes de tus entradas: ::callout{type="tip"} le pasa a Callout.astro la prop type y su contenido en el <slot /> por defecto. Un elemento sin asignar se renderiza como su etiqueta. Pasa por las mismas reglas que el HTML que hace Hollware, así que nada de una entrada ejecuta un script.
  • HollwareImage.astro renderiza la imagen que guarda un campo del frontmatter, con su alt, su tamaño y el srcset de sus copias. Cualquier atributo que le des gana.

También puedes usar render(entry) de Astro: su <Content /> es el HTML que hizo Hollware, y no necesita componentes tuyos.

Listas y traducciones

getLiveCollection('blog', { tag, limit }) lista las entradas, sin su cuerpo, cada una con las imágenes de su frontmatter para HollwareImage.astro. hollwareTranslations(options, group) entrega el { locale, slug } de cada entrada de un grupo de traducción, para enlazarlas.

Vistas previas

Una live collection muestra vistas previas de borradores. Agrega el middleware, que cambia el enlace de vista previa del admin por una cookie:

// src/middleware.ts
import { hollwarePreview } from '@hollware/astro'
export const onRequest = hollwarePreview()
---
import { refusePreview } from '@hollware/astro'
const preview = Astro.locals.hollwarePreview
const { entry, error } = await getLiveEntry('blog', { id: Astro.params.slug!, preview })
if (error) refusePreview(Astro.locals, error)
---

Con un token, la entrada es su última revisión, borrador incluido, y la página nunca se guarda en caché. Un token vencido es un error, nunca la versión publicada. Una colección de compilación no tiene vistas previas: una página estática se compila una vez, para todos.

Un sitio completo

examples/astro-blog en el repositorio es un blog en Astro sobre un Worker que lee el playground en cada solicitud, con su callout como un componente propio.