astro-blog-kit 0.4.0 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -6,10 +6,10 @@ A ready-to-use blog system for Astro with WordPress headless support, optional i
|
|
|
6
6
|
|
|
7
7
|
- 🚀 **One command setup** — `npx astro-blog-kit init`
|
|
8
8
|
- 📝 **WordPress headless** — connects to WordPress REST API out of the box
|
|
9
|
-
- 🎨 **Multiple layouts** — magazine, grid,
|
|
9
|
+
- 🎨 **Multiple layouts** — magazine, featured, grid, cards
|
|
10
10
|
- 💬 **Comment system** — with secure proxy to WordPress
|
|
11
11
|
- 🌍 **Optional i18n** — multi-language support
|
|
12
|
-
- 🎨 **
|
|
12
|
+
- 🎨 **Fully themeable** — colors, fonts, hero texts, and UI labels via `blog.config.ts`
|
|
13
13
|
- 📦 **Zero config** — works without any configuration
|
|
14
14
|
|
|
15
15
|
---
|
|
@@ -47,20 +47,13 @@ And will automatically create:
|
|
|
47
47
|
|
|
48
48
|
```js
|
|
49
49
|
// astro.config.mjs
|
|
50
|
-
import { defineConfig } from
|
|
51
|
-
import { blogKit } from
|
|
50
|
+
import { defineConfig } from 'astro/config';
|
|
51
|
+
import { blogKit } from 'astro-blog-kit/integration';
|
|
52
|
+
import config from './blog.config';
|
|
53
|
+
import { toBlogKitConfig } from 'astro-blog-kit';
|
|
52
54
|
|
|
53
55
|
export default defineConfig({
|
|
54
|
-
integrations: [
|
|
55
|
-
blogKit({
|
|
56
|
-
postsPerPage: 5,
|
|
57
|
-
defaultLayout: "magazine",
|
|
58
|
-
theme: {
|
|
59
|
-
accent: "#facc15",
|
|
60
|
-
fontHeading: "Georgia, serif",
|
|
61
|
-
},
|
|
62
|
-
}),
|
|
63
|
-
],
|
|
56
|
+
integrations: [blogKit(toBlogKitConfig(config))],
|
|
64
57
|
});
|
|
65
58
|
```
|
|
66
59
|
|
|
@@ -93,66 +86,157 @@ npm run dev
|
|
|
93
86
|
### `blog.config.ts`
|
|
94
87
|
|
|
95
88
|
```ts
|
|
96
|
-
import { defineBlogConfig } from
|
|
89
|
+
import { defineBlogConfig } from 'astro-blog-kit';
|
|
97
90
|
|
|
98
91
|
export default defineBlogConfig({
|
|
99
|
-
wpUrl:
|
|
92
|
+
wpUrl: import.meta.env.WP_API_URL || 'https://cms.yourdomain.com',
|
|
100
93
|
postsPerPage: 5,
|
|
101
|
-
defaultLayout:
|
|
102
|
-
locale:
|
|
94
|
+
defaultLayout: 'magazine', // 'magazine' | 'grid' | 'featured' | 'cards'
|
|
95
|
+
locale: 'en', // 'en' | 'es'
|
|
96
|
+
|
|
103
97
|
theme: {
|
|
104
|
-
accent:
|
|
105
|
-
background:
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
98
|
+
accent: '#facc15',
|
|
99
|
+
background: '#ffffff',
|
|
100
|
+
surface: '#f8f8f8',
|
|
101
|
+
text: '#0a0a0a',
|
|
102
|
+
muted: '#6b7280',
|
|
103
|
+
mutedLight: '#9ca3af',
|
|
104
|
+
border: '#e5e7eb',
|
|
105
|
+
black: '#0a0a0a',
|
|
106
|
+
white: '#ffffff',
|
|
107
|
+
fontHeading: 'Georgia, serif',
|
|
108
|
+
fontBody: 'system-ui, sans-serif',
|
|
109
|
+
fontMono: 'monospace',
|
|
110
|
+
fontDisplay: 'Georgia, serif',
|
|
111
|
+
containerMax: '1200px',
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
hero: {
|
|
115
|
+
tagline: 'Our Blog',
|
|
116
|
+
titleLine1: 'Latest',
|
|
117
|
+
titleLine2: 'Articles',
|
|
118
|
+
description: 'Welcome to our blog.',
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
ui: {
|
|
122
|
+
readMoreLabel: 'Read more →',
|
|
123
|
+
btnPrev: 'Previous',
|
|
124
|
+
btnNext: 'Next',
|
|
125
|
+
commentButtonColor: 'var(--bk-accent)',
|
|
126
|
+
commentButtonTextColor: 'var(--bk-black)',
|
|
127
|
+
paginationStyle: 'minimal', // 'minimal' | 'numbered'
|
|
128
|
+
// paginationBtnBg: '#facc15',
|
|
129
|
+
// paginationBtnText: '#0a0a0a',
|
|
130
|
+
// paginationBtnHoverBg: '#0a0a0a',
|
|
131
|
+
// paginationBtnHoverText: '#ffffff',
|
|
132
|
+
// paginationActiveBg: '#facc15',
|
|
133
|
+
// paginationActiveText: '#0a0a0a',
|
|
109
134
|
},
|
|
110
135
|
});
|
|
111
136
|
```
|
|
112
137
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
|
118
|
-
|
|
|
119
|
-
| `
|
|
120
|
-
| `
|
|
121
|
-
| `
|
|
122
|
-
| `
|
|
123
|
-
| `
|
|
124
|
-
| `
|
|
125
|
-
| `
|
|
126
|
-
| `
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
### theme
|
|
141
|
+
|
|
142
|
+
| Property | Default | Description |
|
|
143
|
+
| :------------- | :---------------------- | :---------------------------------- |
|
|
144
|
+
| `accent` | `#facc15` | Primary accent color |
|
|
145
|
+
| `background` | `#ffffff` | Blog section background |
|
|
146
|
+
| `surface` | `#f8f8f8` | Cards and sidebar background |
|
|
147
|
+
| `text` | `#0a0a0a` | Primary text color |
|
|
148
|
+
| `muted` | `#6b7280` | Secondary text color |
|
|
149
|
+
| `mutedLight` | `#9ca3af` | Subtle text color |
|
|
150
|
+
| `border` | `#e5e7eb` | Border color |
|
|
151
|
+
| `black` | `#0a0a0a` | Badge and title highlight |
|
|
152
|
+
| `white` | `#ffffff` | Text on dark backgrounds |
|
|
153
|
+
| `fontHeading` | `Georgia, serif` | Heading font |
|
|
154
|
+
| `fontBody` | `system-ui, sans-serif` | Body font |
|
|
155
|
+
| `fontMono` | `monospace` | Monospace font |
|
|
156
|
+
| `fontDisplay` | `Georgia, serif` | Display/hero font |
|
|
157
|
+
| `containerMax` | `1200px` | Max width of the blog container |
|
|
127
158
|
|
|
128
159
|
---
|
|
129
160
|
|
|
130
|
-
|
|
161
|
+
### hero
|
|
162
|
+
|
|
163
|
+
| Property | Default | Description |
|
|
164
|
+
| :------------ | :--------------------- | :------------------------------ |
|
|
165
|
+
| `tagline` | `Our Blog` | Badge text above the title |
|
|
166
|
+
| `titleLine1` | `Latest` | First line of the hero title |
|
|
167
|
+
| `titleLine2` | `Articles` | Second line (highlighted) |
|
|
168
|
+
| `description` | `Welcome to our blog.` | Paragraph below the title |
|
|
131
169
|
|
|
132
|
-
|
|
133
|
-
Featured post on the left + smaller posts on the right.
|
|
170
|
+
---
|
|
134
171
|
|
|
135
|
-
###
|
|
136
|
-
|
|
172
|
+
### ui
|
|
173
|
+
|
|
174
|
+
| Property | Default | Description |
|
|
175
|
+
| :----------------------- | :----------------- | :--------------------------------- |
|
|
176
|
+
| `readMoreLabel` | `Read more →` | Read more button label |
|
|
177
|
+
| `btnPrev` | `Previous` | Previous page button label |
|
|
178
|
+
| `btnNext` | `Next` | Next page button label |
|
|
179
|
+
| `commentButtonColor` | `var(--bk-accent)` | Comment submit button background |
|
|
180
|
+
| `commentButtonTextColor` | `var(--bk-black)` | Comment submit button text color |
|
|
181
|
+
| `paginationStyle` | `minimal` | `minimal` or `numbered` |
|
|
182
|
+
| `paginationBtnBg` | `accent` | PREV/NEXT button background |
|
|
183
|
+
| `paginationBtnText` | `black` | PREV/NEXT button text color |
|
|
184
|
+
| `paginationBtnHoverBg` | `text` | PREV/NEXT button hover background |
|
|
185
|
+
| `paginationBtnHoverText` | `white` | PREV/NEXT button hover text color |
|
|
186
|
+
| `paginationActiveBg` | `accent` | Active page number background |
|
|
187
|
+
| `paginationActiveText` | `black` | Active page number text color |
|
|
137
188
|
|
|
138
|
-
|
|
139
|
-
Horizontal rows with image on the left.
|
|
189
|
+
---
|
|
140
190
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
191
|
+
## CSS Variables
|
|
192
|
+
|
|
193
|
+
All theme values are available globally with the `--bk-` prefix:
|
|
194
|
+
|
|
195
|
+
```css
|
|
196
|
+
var(--bk-accent)
|
|
197
|
+
var(--bk-background)
|
|
198
|
+
var(--bk-surface)
|
|
199
|
+
var(--bk-text)
|
|
200
|
+
var(--bk-muted)
|
|
201
|
+
var(--bk-muted-light)
|
|
202
|
+
var(--bk-border)
|
|
203
|
+
var(--bk-black)
|
|
204
|
+
var(--bk-white)
|
|
205
|
+
var(--bk-font-heading)
|
|
206
|
+
var(--bk-font-body)
|
|
207
|
+
var(--bk-font-mono)
|
|
208
|
+
var(--bk-font-display)
|
|
209
|
+
var(--bk-container-max)
|
|
210
|
+
var(--bk-pagination-btn-bg)
|
|
211
|
+
var(--bk-pagination-btn-text)
|
|
212
|
+
var(--bk-pagination-btn-hover-bg)
|
|
213
|
+
var(--bk-pagination-btn-hover-text)
|
|
214
|
+
var(--bk-pagination-active-bg)
|
|
215
|
+
var(--bk-pagination-active-text)
|
|
216
|
+
var(--bk-comment-btn-bg)
|
|
217
|
+
var(--bk-comment-btn-text)
|
|
145
218
|
```
|
|
146
219
|
|
|
147
220
|
---
|
|
148
221
|
|
|
222
|
+
## Layouts
|
|
223
|
+
|
|
224
|
+
| Layout | Description |
|
|
225
|
+
| :---------- | :------------------------------------ |
|
|
226
|
+
| `magazine` | Featured post + side grid |
|
|
227
|
+
| `grid` | 3-column card grid |
|
|
228
|
+
| `featured` | Large hero image + grid below |
|
|
229
|
+
| `cards` | Image background with text overlay |
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
149
233
|
## Components
|
|
150
234
|
|
|
151
235
|
### `<BlogList>`
|
|
152
236
|
|
|
153
237
|
```astro
|
|
154
238
|
---
|
|
155
|
-
import { BlogList } from
|
|
239
|
+
import { BlogList } from 'astro-blog-kit/components';
|
|
156
240
|
---
|
|
157
241
|
<BlogList
|
|
158
242
|
posts={posts}
|
|
@@ -161,7 +245,7 @@ import { BlogList } from "astro-blog-kit/components";
|
|
|
161
245
|
basePath="/blog/page/"
|
|
162
246
|
blogBase="/blog/"
|
|
163
247
|
dateLocale="en-US"
|
|
164
|
-
t={
|
|
248
|
+
t={bt}
|
|
165
249
|
locale="en"
|
|
166
250
|
layout="magazine"
|
|
167
251
|
/>
|
|
@@ -171,7 +255,7 @@ import { BlogList } from "astro-blog-kit/components";
|
|
|
171
255
|
|
|
172
256
|
```astro
|
|
173
257
|
---
|
|
174
|
-
import { BlogPost } from
|
|
258
|
+
import { BlogPost } from 'astro-blog-kit/components';
|
|
175
259
|
---
|
|
176
260
|
<BlogPost post={post} t={t} lang="en" />
|
|
177
261
|
```
|
|
@@ -180,7 +264,7 @@ import { BlogPost } from "astro-blog-kit/components";
|
|
|
180
264
|
|
|
181
265
|
```astro
|
|
182
266
|
---
|
|
183
|
-
import { Comments } from
|
|
267
|
+
import { Comments } from 'astro-blog-kit/components';
|
|
184
268
|
---
|
|
185
269
|
<Comments comments={comments} postId={post.id ?? 0} />
|
|
186
270
|
```
|
|
@@ -189,7 +273,7 @@ import { Comments } from "astro-blog-kit/components";
|
|
|
189
273
|
|
|
190
274
|
```astro
|
|
191
275
|
---
|
|
192
|
-
import { CommentForm } from
|
|
276
|
+
import { CommentForm } from 'astro-blog-kit/components';
|
|
193
277
|
---
|
|
194
278
|
<CommentForm postId={post.id ?? 0} apiRoute="/api/comments" />
|
|
195
279
|
```
|
|
@@ -201,30 +285,21 @@ import { CommentForm } from "astro-blog-kit/components";
|
|
|
201
285
|
### WordPress client
|
|
202
286
|
|
|
203
287
|
```ts
|
|
204
|
-
import { createWPClient } from
|
|
288
|
+
import { createWPClient } from 'astro-blog-kit/utils';
|
|
205
289
|
|
|
206
|
-
const wp = createWPClient(
|
|
290
|
+
const wp = createWPClient('https://cms.yourdomain.com');
|
|
207
291
|
|
|
208
|
-
// Get paginated posts
|
|
209
292
|
const { posts, total, totalPages } = await wp.getPosts({ perPage: 5, page: 1 });
|
|
210
|
-
|
|
211
|
-
// Get all posts (for getStaticPaths)
|
|
212
293
|
const posts = await wp.getAllPosts();
|
|
213
|
-
|
|
214
|
-
// Get single post by slug
|
|
215
|
-
const post = await wp.getPost("my-post-slug");
|
|
216
|
-
|
|
217
|
-
// Get comments for a post
|
|
294
|
+
const post = await wp.getPost('my-post-slug');
|
|
218
295
|
const comments = await wp.getComments(postId);
|
|
219
|
-
|
|
220
|
-
// Get categories
|
|
221
296
|
const categories = await wp.getCategories();
|
|
222
297
|
```
|
|
223
298
|
|
|
224
299
|
### i18n helpers
|
|
225
300
|
|
|
226
301
|
```ts
|
|
227
|
-
import { getLang, useTranslations, getBlogBase } from
|
|
302
|
+
import { getLang, useTranslations, getBlogBase } from 'astro-blog-kit/utils';
|
|
228
303
|
|
|
229
304
|
const lang = getLang(Astro.url, import.meta.env.BASE_URL, config);
|
|
230
305
|
const t = useTranslations(lang, { en, es });
|
|
@@ -234,12 +309,9 @@ const blogBase = getBlogBase(lang, import.meta.env.BASE_URL, config);
|
|
|
234
309
|
### Static paths helpers
|
|
235
310
|
|
|
236
311
|
```ts
|
|
237
|
-
import { getStaticPathsForPosts, getStaticPathsForPages } from
|
|
312
|
+
import { getStaticPathsForPosts, getStaticPathsForPages } from 'astro-blog-kit/utils';
|
|
238
313
|
|
|
239
|
-
// For [...slug].astro
|
|
240
314
|
export const getStaticPaths = () => getStaticPathsForPosts(posts);
|
|
241
|
-
|
|
242
|
-
// For [page].astro
|
|
243
315
|
export const getStaticPaths = () => getStaticPathsForPages(posts, { postsPerPage: 5 });
|
|
244
316
|
```
|
|
245
317
|
|
|
@@ -251,19 +323,12 @@ Copy `node_modules/astro-blog-kit/examples/deploy-ftp.yml` to `.github/workflows
|
|
|
251
323
|
|
|
252
324
|
Add these secrets to your GitHub repository (**Settings → Secrets**):
|
|
253
325
|
|
|
254
|
-
| Secret
|
|
255
|
-
|
|
256
|
-
| `FTP_HOST`
|
|
257
|
-
| `FTP_USERNAME
|
|
258
|
-
| `FTP_PASSWORD
|
|
259
|
-
| `WP_API_URL`
|
|
260
|
-
|
|
261
|
-
The workflow triggers on:
|
|
262
|
-
- Push to `main`
|
|
263
|
-
- WordPress webhook (`wp_update`, `wp_comment`)
|
|
264
|
-
- Manual trigger
|
|
265
|
-
|
|
266
|
-
To trigger from WordPress, install the **WP Webhooks** plugin and configure it to send a `repository_dispatch` event to GitHub when a post is published or a comment is approved.
|
|
326
|
+
| Secret | Description |
|
|
327
|
+
| :------------ | :-------------------- |
|
|
328
|
+
| `FTP_HOST` | Your server hostname |
|
|
329
|
+
| `FTP_USERNAME`| FTP username |
|
|
330
|
+
| `FTP_PASSWORD`| FTP password |
|
|
331
|
+
| `WP_API_URL` | Your WordPress URL |
|
|
267
332
|
|
|
268
333
|
---
|
|
269
334
|
|
|
@@ -273,8 +338,8 @@ To trigger from WordPress, install the **WP Webhooks** plugin and configure it t
|
|
|
273
338
|
// astro.config.mjs
|
|
274
339
|
blogKit({
|
|
275
340
|
i18n: {
|
|
276
|
-
locales: [
|
|
277
|
-
defaultLocale:
|
|
341
|
+
locales: ['en', 'es'],
|
|
342
|
+
defaultLocale: 'en',
|
|
278
343
|
},
|
|
279
344
|
})
|
|
280
345
|
```
|
|
@@ -287,7 +352,7 @@ With i18n enabled:
|
|
|
287
352
|
|
|
288
353
|
## Requirements
|
|
289
354
|
|
|
290
|
-
- Astro v4 or
|
|
355
|
+
- Astro v4, v5, v6, or v7
|
|
291
356
|
- Node.js 18+
|
|
292
357
|
- WordPress with REST API enabled
|
|
293
358
|
|
package/package.json
CHANGED
|
@@ -7,20 +7,20 @@ export default defineBlogConfig({
|
|
|
7
7
|
locale: '__LOCALE__',
|
|
8
8
|
|
|
9
9
|
theme: {
|
|
10
|
-
accent:
|
|
11
|
-
background:
|
|
12
|
-
surface:
|
|
13
|
-
text:
|
|
14
|
-
muted:
|
|
15
|
-
mutedLight:
|
|
16
|
-
border:
|
|
17
|
-
black:
|
|
18
|
-
white:
|
|
19
|
-
fontHeading:
|
|
20
|
-
fontBody:
|
|
21
|
-
fontMono:
|
|
22
|
-
fontDisplay:
|
|
23
|
-
containerMax:'1200px',
|
|
10
|
+
accent: '#facc15',
|
|
11
|
+
background: '#ffffff',
|
|
12
|
+
surface: '#f8f8f8',
|
|
13
|
+
text: '#0a0a0a',
|
|
14
|
+
muted: '#6b7280',
|
|
15
|
+
mutedLight: '#4b5563',
|
|
16
|
+
border: '#e5e7eb',
|
|
17
|
+
black: '#0a0a0a',
|
|
18
|
+
white: '#ffffff',
|
|
19
|
+
fontHeading: 'Georgia, serif',
|
|
20
|
+
fontBody: 'system-ui, sans-serif',
|
|
21
|
+
fontMono: 'monospace',
|
|
22
|
+
fontDisplay: 'Georgia, serif',
|
|
23
|
+
containerMax: '1200px',
|
|
24
24
|
},
|
|
25
25
|
|
|
26
26
|
hero: {
|
|
@@ -37,5 +37,14 @@ export default defineBlogConfig({
|
|
|
37
37
|
commentButtonColor: 'var(--bk-accent)',
|
|
38
38
|
commentButtonTextColor: 'var(--bk-black)',
|
|
39
39
|
paginationStyle: 'minimal',
|
|
40
|
+
// ── Personalización de paginación (opcional) ──────────────
|
|
41
|
+
// Descomenta y cambia los valores según tu marca.
|
|
42
|
+
// Por defecto usan el accent y black del tema.
|
|
43
|
+
// paginationBtnBg: '#facc15', // fondo botón PREV/NEXT
|
|
44
|
+
// paginationBtnText: '#0a0a0a', // texto botón PREV/NEXT
|
|
45
|
+
// paginationBtnHoverBg: '#0a0a0a', // fondo hover
|
|
46
|
+
// paginationBtnHoverText: '#ffffff', // texto hover
|
|
47
|
+
// paginationActiveBg: '#facc15', // fondo página activa
|
|
48
|
+
// paginationActiveText: '#0a0a0a', // texto página activa
|
|
40
49
|
},
|
|
41
50
|
});
|
|
@@ -12,7 +12,7 @@ const locale = config.locale ?? 'en';
|
|
|
12
12
|
const hero = resolveHero(config.hero, locale);
|
|
13
13
|
const ui = resolveUI(config.ui, locale);
|
|
14
14
|
|
|
15
|
-
const
|
|
15
|
+
const bt = {
|
|
16
16
|
blog: {
|
|
17
17
|
tagline: hero.tagline,
|
|
18
18
|
title_line1: hero.titleLine1,
|
|
@@ -35,7 +35,7 @@ __LAYOUT_OPEN__
|
|
|
35
35
|
basePath={`${base}blog/page/`}
|
|
36
36
|
blogBase={`${base}blog/`}
|
|
37
37
|
dateLocale={locale}
|
|
38
|
-
t={
|
|
38
|
+
t={bt}
|
|
39
39
|
locale={locale}
|
|
40
40
|
layout={config.defaultLayout ?? 'magazine'}
|
|
41
41
|
/>
|
|
@@ -13,7 +13,11 @@ export async function getStaticPaths() {
|
|
|
13
13
|
|
|
14
14
|
const { posts, currentPage, totalPages } = Astro.props;
|
|
15
15
|
|
|
16
|
-
const
|
|
16
|
+
const locale = config.locale ?? 'en';
|
|
17
|
+
const hero = resolveHero(config.hero, locale);
|
|
18
|
+
const ui = resolveUI(config.ui, locale);
|
|
19
|
+
|
|
20
|
+
const bt = {
|
|
17
21
|
blog: {
|
|
18
22
|
tagline: hero.tagline,
|
|
19
23
|
title_line1: hero.titleLine1,
|
|
@@ -16,7 +16,11 @@ const { post } = Astro.props;
|
|
|
16
16
|
const wp = createWPClient(config.wpUrl);
|
|
17
17
|
const comments = post.id ? await wp.getComments(post.id) : [];
|
|
18
18
|
|
|
19
|
-
const
|
|
19
|
+
const locale = config.locale ?? 'en';
|
|
20
|
+
const hero = resolveHero(config.hero, locale);
|
|
21
|
+
const ui = resolveUI(config.ui, locale);
|
|
22
|
+
|
|
23
|
+
const bt = {
|
|
20
24
|
blog: {
|
|
21
25
|
tagline: hero.tagline,
|
|
22
26
|
title_line1: hero.titleLine1,
|