feat: enable full dynamic homepage content via EmDash
- Add homepage singleton collection with 30+ editable fields
- Update index.astro to fetch from getEmDashEntry("homepage", "homepage-main")
- Update Base.astro footer tagline/copyright from EmDash
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,19 @@
|
||||
---
|
||||
import { getSiteSettings } from "emdash";
|
||||
import { getEmDashEntry } from "emdash";
|
||||
import Base from "../layouts/Base.astro";
|
||||
|
||||
const settings = await getSiteSettings();
|
||||
const { entry: homepage } = await getEmDashEntry("homepage", "homepage-main");
|
||||
const { hero_headline, hero_subtitle, hero_button_text, hero_button_url, hero_image,
|
||||
features_section_title, features_section_subtitle,
|
||||
feature_1_title, feature_1_description, feature_1_icon,
|
||||
feature_2_title, feature_2_description, feature_2_icon,
|
||||
feature_3_title, feature_3_description, feature_3_icon,
|
||||
feature_4_title, feature_4_description, feature_4_icon,
|
||||
feature_5_title, feature_5_description, feature_5_icon,
|
||||
feature_6_title, feature_6_description, feature_6_icon,
|
||||
comparison_title, comparison_subtitle,
|
||||
cta_title, cta_subtitle, cta_button_text, cta_button_url,
|
||||
footer_tagline, footer_about_text, footer_copyright } = homepage.data;
|
||||
---
|
||||
<Base title="EmDash CMS - Self-Hosted for Astro" description="Fully self-hosted CMS for Astro. No cloud required, fully local, with admin panel, authentication, and plugin system.">
|
||||
<main class="landing">
|
||||
@@ -11,23 +22,20 @@ const settings = await getSiteSettings();
|
||||
<div class="hero-content">
|
||||
<div class="badge">Open Source • 10k+ Stars</div>
|
||||
<h1 class="hero-title">
|
||||
The CMS that<br />
|
||||
<span class="accent">runs on your server</span>
|
||||
{hero_headline.split('\n').map((line: string) => <><span>{line}</span><br /></>)}
|
||||
</h1>
|
||||
<p class="hero-subtitle">
|
||||
EmDash is a full-stack TypeScript CMS built on Astro.
|
||||
No cloud account required, no external dependencies.
|
||||
Just a complete admin panel and your content.
|
||||
{hero_subtitle}
|
||||
</p>
|
||||
<div class="hero-actions">
|
||||
<a href="/_emdash/admin" class="btn btn-primary">
|
||||
<a href={hero_button_url} class="btn btn-primary">
|
||||
<span class="btn-icon">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
||||
<rect x="3" y="3" width="18" height="18" rx="2"/>
|
||||
<path d="M3 9h18M9 21V9"/>
|
||||
</svg>
|
||||
</span>
|
||||
Open Admin Panel
|
||||
{hero_button_text}
|
||||
</a>
|
||||
<a href="https://github.com/emdash-cms/emdash" class="btn btn-secondary" target="_blank">
|
||||
View on GitHub
|
||||
@@ -61,8 +69,8 @@ const settings = await getSiteSettings();
|
||||
<!-- Features Section -->
|
||||
<section class="features" id="features">
|
||||
<div class="section-header">
|
||||
<h2 class="section-title">Everything you need</h2>
|
||||
<p class="section-subtitle">A complete CMS without the vendor lock-in</p>
|
||||
<h2 class="section-title">{features_section_title}</h2>
|
||||
<p class="section-subtitle">{features_section_subtitle}</p>
|
||||
</div>
|
||||
<div class="features-grid">
|
||||
<div class="feature-card">
|
||||
@@ -73,11 +81,8 @@ const settings = await getSiteSettings();
|
||||
<path d="M2 12l10 5 10-5"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="feature-title">Fully Self-Hosted</h3>
|
||||
<p class="feature-desc">
|
||||
SQLite, D1, Turso, or PostgreSQL. Your data stays on your servers.
|
||||
No cloud account required.
|
||||
</p>
|
||||
<h3 class="feature-title">{feature_1_title}</h3>
|
||||
<p class="feature-desc">{feature_1_description}</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon">
|
||||
@@ -86,11 +91,8 @@ const settings = await getSiteSettings();
|
||||
<path d="M3 9h18M9 21V9"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="feature-title">Admin Panel</h3>
|
||||
<p class="feature-desc">
|
||||
Visual schema builder, media library, navigation menus.
|
||||
Full admin at /_emdash/admin
|
||||
</p>
|
||||
<h3 class="feature-title">{feature_2_title}</h3>
|
||||
<p class="feature-desc">{feature_2_description}</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon">
|
||||
@@ -98,11 +100,8 @@ const settings = await getSiteSettings();
|
||||
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="feature-title">Passkey Auth</h3>
|
||||
<p class="feature-desc">
|
||||
WebAuthn passkey-first authentication with OAuth and magic link fallbacks.
|
||||
Role-based access control.
|
||||
</p>
|
||||
<h3 class="feature-title">{feature_3_title}</h3>
|
||||
<p class="feature-desc">{feature_3_description}</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon">
|
||||
@@ -111,11 +110,8 @@ const settings = await getSiteSettings();
|
||||
<path d="M12 6v6l4 2"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="feature-title">Built-in MCP</h3>
|
||||
<p class="feature-desc">
|
||||
Model Context Protocol server for AI tools.
|
||||
Claude and ChatGPT can interact with your site directly.
|
||||
</p>
|
||||
<h3 class="feature-title">{feature_4_title}</h3>
|
||||
<p class="feature-desc">{feature_4_description}</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon">
|
||||
@@ -124,11 +120,8 @@ const settings = await getSiteSettings();
|
||||
<polyline points="8 6 2 12 8 18"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="feature-title">Plugin System</h3>
|
||||
<p class="feature-desc">
|
||||
Sandboxed plugins on Cloudflare Workers.
|
||||
Define capabilities, run safely in isolation.
|
||||
</p>
|
||||
<h3 class="feature-title">{feature_5_title}</h3>
|
||||
<p class="feature-desc">{feature_5_description}</p>
|
||||
</div>
|
||||
<div class="feature-card">
|
||||
<div class="feature-icon">
|
||||
@@ -139,11 +132,8 @@ const settings = await getSiteSettings();
|
||||
<line x1="16" y1="17" x2="8" y2="17"/>
|
||||
</svg>
|
||||
</div>
|
||||
<h3 class="feature-title">WordPress Import</h3>
|
||||
<p class="feature-desc">
|
||||
Import posts, pages, media, and taxonomies from WXR exports,
|
||||
REST API, or WordPress.com.
|
||||
</p>
|
||||
<h3 class="feature-title">{feature_6_title}</h3>
|
||||
<p class="feature-desc">{feature_6_description}</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -151,8 +141,8 @@ const settings = await getSiteSettings();
|
||||
<!-- Comparison Section -->
|
||||
<section class="comparison">
|
||||
<div class="section-header">
|
||||
<h2 class="section-title">EmDash vs Tina CMS</h2>
|
||||
<p class="section-subtitle">Both work with Astro, but differ in approach</p>
|
||||
<h2 class="section-title">{comparison_title}</h2>
|
||||
<p class="section-subtitle">{comparison_subtitle}</p>
|
||||
</div>
|
||||
<div class="comparison-table">
|
||||
<div class="comparison-header">
|
||||
@@ -196,14 +186,10 @@ const settings = await getSiteSettings();
|
||||
<!-- CTA Section -->
|
||||
<section class="cta">
|
||||
<div class="cta-content">
|
||||
<h2 class="cta-title">Ready to get started?</h2>
|
||||
<p class="cta-subtitle">
|
||||
Clone the template, run bootstrap, and you're ready to build.
|
||||
</p>
|
||||
<h2 class="cta-title">{cta_title}</h2>
|
||||
<p class="cta-subtitle">{cta_subtitle}</p>
|
||||
<div class="cta-actions">
|
||||
<a href="/_emdash/admin" class="btn btn-primary btn-large">
|
||||
Try Admin Panel
|
||||
</a>
|
||||
<a href={cta_button_url} class="btn btn-primary btn-large">{cta_button_text}</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
Reference in New Issue
Block a user