Schemat w kodzie. Treść przez HTTP.

Zdefiniuj kolekcje w TypeScript, edytuj je w panelu, czytaj przez REST, GraphQL albo loader Astro. Hostowany w UE, albo na twoich własnych serwerach.

Panel Osprey podczas edycji opublikowanej strony bezpośrednio na niej: strona na żywo pośrodku z czternastoma zaznaczonymi polami do edycji, lista pól po lewej, wybór języka i przycisk Publikuj na pasku. Panel Osprey podczas edycji opublikowanej strony bezpośrednio na niej: strona na żywo pośrodku z czternastoma zaznaczonymi polami do edycji, lista pól po lewej, wybór języka i przycisk Publikuj na pasku.
Panel podczas edycji strony na żywo. Zrzut ekranu, nie makieta. Panel istnieje po angielsku i włosku, więc te zrzuty to zestaw angielski.

Cztery rzeczy, które możesz sprawdzić.

  • Schemat Czternaście typów pól Tekst, textarea, rich text, liczba, boolean, data i czas, slug, select, relacja, media, grupa, tablica, JSON, bloki. Wszystkie eksportowane przez pakiet core.
  • Odczyt publiczny Bez klucza, domyślnie 404 Kolekcję da się czytać bez klucza tylko wtedy, gdy jej reguła dostępu dopuszcza anonimowe wywołanie. Wszystko inne odpowiada 404, nigdy 403.
  • Języki Dziesięć języków treści Pola lokalizowane, macierz pokrycia dla każdej strony i języka, a braki w pliku CSV.
  • Klucze Hashowane, pokazane raz Klucze API są zapisane jako hash HMAC z pepperem. Widzisz klucz przy tworzeniu; panel zachowuje ostatnie cztery znaki.
Każda funkcja, szczegółowo →

Od pliku TypeScript do strony w sieci.

Przewiń. Ta sama treść, na każdym z czterech przystanków.

  1. 01 · Schemat

    Definiujesz kolekcję w TypeScript.

    Slug, pola, reguły dostępu. Żyje w twoim repozytorium i przechodzi review jak każdy inny kod.

    content/blog-post.tsTS
    import { defineCollection, fields } from '@osprey/core'
    
    export const blogPost = defineCollection({
      slug: 'blog-post',
      access: { read: () => true },
      fields: {
        slug:        fields.slug({ from: 'title' }),
        locale:      fields.text({ required: true }),
        title:       fields.text({ required: true }),
        excerpt:     fields.textarea(),
        body:        fields.richText({ required: true }),
        publishedAt: fields.datetime(),
      },
    })
  2. 02 · Panel

    Panel czyta schemat i rysuje formularz.

    Pola wymagane, wybór języka, treść w rich text. Niczego nie konfigurujesz dwa razy.

  3. 03 · API

    Opublikowane wpisy wychodzą jako JSON.

    Jeden GET, bez klucza, z SEO, canonical i hreflang już scalonymi w każdym wpisie.

    entriesHTTP
    GET /api/v1/collections/blog-post/entries?locale=en
    Host: cms.altovar.net
    
    200 OK
    { "data": [ {
        "id": "fdoc_16d9i3ef",
        "data":       { "title": "EU-first content infrastructure", … },
        "seo":        { "metaTitle": "EU-first content infrastructure", … },
        "canonical":  "https://…/en/eu-first-content-infrastructure",
        "alternates": { "en": …, "x-default": … }
      } ],
      "pagination": { "page": 1, "limit": 20, "total": 3 } }
  4. 04 · Strona

    Twój frontend je renderuje.

    Loader Astro pobiera wpisy podczas builda. Blog poniżej jest zbudowany dokładnie tak, z tego CMS-a.

    Otwórz blog na żywo →
    src/content.config.tsASTRO
    import { defineCollection } from 'astro:content'
    import { ospreyLoader } from '@osprey/astro'
    
    const blog = defineCollection({
      loader: ospreyLoader({
        collection: 'blog-post',
        baseUrl:    'https://cms.altovar.net',
        tenantId:   'altovar',
      }),
    })

Panel w twoim motywie i twoim języku.

Jasny lub ciemny, angielski lub włoski. Każdy zrzut na tej stronie podąża za motywem, który wybierzesz w nagłówku: to ten sam panel, sfotografowany dwa razy.

Twoja treść. Twój serwer. Dziś.

Darmowy plan, bez karty. Hostowany w UE, albo na twoich własnych maszynach.