SQLite
Développement local avec sqlite({ url: "file:./data.db" })
EmDash s’intègre profondément avec Astro pour offrir une expérience CMS complète. Cette page explique les principales décisions architecturales et comment les pièces s’assemblent.
┌──────────────────────────────────────────────────────────────────┐│ Votre site Astro ││ ││ ┌────────────────────────────────────────────────────────────┐ ││ │ Intégration EmDash │ ││ │ │ ││ │ ┌──────────────┐ ┌──────────────┐ ┌───────────────┐ │ ││ │ │ API │ │ Panneau │ │ Plugins │ │ ││ │ │ de contenu │ │ admin │ │ │ │ ││ │ └──────────────┘ └──────────────┘ └───────────────┘ │ ││ │ │ ││ │ ┌──────────────────────────────────────────────────────┐ │ ││ │ │ Couche de données │ │ ││ │ │ Base de données (D1/SQLite) + Stockage (R2/S3) │ │ ││ │ └──────────────────────────────────────────────────────┘ │ ││ └────────────────────────────────────────────────────────────┘ ││ ││ ┌────────────────────────────────────────────────────────────┐ ││ │ Framework Astro │ ││ │ Live Collections · Middleware · Sessions │ ││ └────────────────────────────────────────────────────────────┘ │└──────────────────────────────────────────────────────────────────┘EmDash s’exécute en tant qu’intégration Astro. Il injecte des routes pour le panneau d’administration et les API REST, fournit un chargeur de contenu pour les Collections en Direct, et gère les migrations de base de données et les connexions de stockage.
Contrairement aux CMS traditionnels qui définissent le schéma dans le code, EmDash stocke les définitions de schéma dans la base de données elle-même. Deux tables système suivent la structure de votre contenu :
_emdash_collections — Métadonnées des collections (slug, libellé, fonctionnalités)_emdash_fields — Définitions des champs pour chaque collectionLorsque vous créez une collection “produits” avec des champs titre et prix via l’interface d’administration, EmDash :
_emdash_collections et _emdash_fieldsALTER TABLE pour créer ec_products avec les colonnes appropriéesCette conception permet :
Chaque collection obtient sa propre table SQLite avec le préfixe ec_ :
-- Créée lorsque la collection "posts" est ajoutéeCREATE TABLE ec_posts ( -- Colonnes système (toujours présentes) id TEXT PRIMARY KEY, slug TEXT UNIQUE, status TEXT DEFAULT 'draft', -- draft, published, scheduled author_id TEXT, created_at TEXT DEFAULT (datetime('now')), updated_at TEXT DEFAULT (datetime('now')), published_at TEXT, deleted_at TEXT, -- Suppression logique version INTEGER DEFAULT 1, -- Verrou optimiste
-- Colonnes de contenu (à partir de vos définitions de champs) title TEXT NOT NULL, content JSON, -- Portable Text excerpt TEXT);Pourquoi des tables par collection plutôt qu’une seule table de contenu avec du JSON ?
EmDash utilise les Collections en Direct d’Astro 6 pour servir le contenu à l’exécution. Les modifications de contenu sont immédiatement disponibles sans reconstructions statiques.
Le emdashLoader() implémente l’interface LiveLoader d’Astro :
import { defineLiveCollection } from "astro:content";import { emdashLoader } from "emdash/runtime";
export const collections = { _emdash: defineLiveCollection({ loader: emdashLoader() }),};Interrogez le contenu en utilisant les fonctions wrapper fournies :
import { getEmDashCollection, getEmDashEntry } from "emdash";
// Obtenir tous les articles publiésconst { entries: posts } = await getEmDashCollection("posts");
// Obtenir les brouillonsconst { entries: drafts } = await getEmDashCollection("posts", { status: "draft",});
// Obtenir une entrée unique par slugconst { entry: post } = await getEmDashEntry("posts", "my-post-slug");L’intégration EmDash utilise l’API injectRoute d’Astro pour ajouter des routes d’administration et d’API :
| Modèle de Chemin | Objectif |
|---|---|
/_emdash/admin/[...path] | Application monopage du panneau d’administration |
/_emdash/api/manifest | Manifeste d’administration (collections, plugins) |
/_emdash/api/content/[collection] | CRUD pour les entrées de contenu |
/_emdash/api/media/* | Opérations de la bibliothèque multimédia |
/_emdash/api/schema/* | Gestion du schéma |
/_emdash/api/settings | Paramètres du site |
/_emdash/api/menus/* | Menus de navigation |
/_emdash/api/taxonomies/* | Catégories, étiquettes, taxonomies personnalisées |
Les routes sont injectées depuis le package emdash — rien n’est copié dans votre projet.
EmDash utilise Kysely pour des requêtes SQL typées sur toutes les bases de données prises en charge :
SQLite
Développement local avec sqlite({ url: "file:./data.db" })
D1
SQL serverless de Cloudflare avec d1({ binding: "DB" })
libSQL
SQLite distant avec libsql({ url: "...", authToken: "..." })
La configuration de la base de données est passée à l’intégration dans astro.config.mjs :
import { defineConfig } from "astro/config";import emdash from "emdash/astro";import { sqlite } from "emdash/db";import { local } from "emdash/storage";
export default defineConfig({ integrations: [ emdash({ database: sqlite({ url: "file:./data.db" }), storage: local({ directory: "./uploads", baseUrl: "/_emdash/api/media/file", }), }), ],});Les fichiers multimédias sont stockés séparément de la base de données. EmDash prend en charge :
Les téléversements utilisent des URL signées pour des téléversements directs du client vers le stockage, contournant les limites de taille de corps des Workers.
Les plugins étendent EmDash via un système de hooks inspiré de WordPress :
content:beforeSave, content:afterSave, content:beforeDelete, content:afterDeletemedia:beforeUpload, media:afterUploadLes plugins peuvent s’exécuter dans deux modes :
import { seoPlugin } from "@emdash-cms/plugin-seo";
emdash({ plugins: [seoPlugin({ maxTitleLength: 60 })],});Une requête de contenu typique suit ce chemin :
Astro reçoit la requête
Votre composant de page s’exécute.
Le contenu est interrogé
getEmDashCollection() appelle getLiveCollection() d’Astro.
Le chargeur s’exécute
emdashLoader interroge la table ec_* correspondante via Kysely.
Les données sont renvoyées
Les entrées sont mappées au format d’Astro avec id, slug et data.
La page est rendue
Votre composant reçoit le contenu et génère le HTML.
Pour les requêtes d’administration :
Le middleware authentifie
Il valide le jeton de session.
La route API traite la requête
Les opérations CRUD passent par les dépôts.
Les hooks sont déclenchés
beforeCreate, afterUpdate et les autres hooks s’exécutent.
La base de données est mise à jour
Kysely exécute le SQL nécessaire.
La réponse est renvoyée
L’application d’administration reçoit une réponse JSON.
EmDash génère des modules virtuels au moment de la compilation pour configurer l’exécution :
| Module | Objectif |
|---|---|
virtual:emdash/config | Configuration de la base de données et du stockage |
virtual:emdash/dialect | Fabrique de dialecte de base de données |
virtual:emdash/plugin-admins | Importations statiques pour les interfaces d’administration des plugins |
Cette approche garantit que les bundlers peuvent correctement résoudre et élaguer le code des plugins.
Collections
Découvrez les collections de contenu et les types de champs.
Modèle de contenu
Comprenez le modèle de contenu axé sur la base de données.
Panneau d'administration
Explorez l’architecture du panneau d’administration.