@studiocms/blog 0.1.0-beta.7 → 0.1.0-beta.8
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/LICENSE +1 -1
- package/dist/blog.d.js +0 -0
- package/dist/blog.d.ts +8 -0
- package/dist/components/BaseHead.astro +73 -0
- package/dist/components/Footer.astro +26 -0
- package/dist/components/Navigation.astro +83 -0
- package/dist/components/PageList.astro +46 -0
- package/{src → dist}/components/PostHeader.astro +1 -23
- package/dist/components/navigation.css +155 -0
- package/dist/components.d.js +0 -0
- package/dist/components.d.ts +13 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.js +81 -0
- package/dist/layouts/Layout.astro +60 -0
- package/dist/lib.d.js +0 -0
- package/dist/lib.d.ts +82 -0
- package/dist/renderer.d.js +0 -0
- package/dist/renderer.d.ts +9 -0
- package/dist/routes/[...slug].astro +36 -0
- package/dist/routes/blog/[...slug].astro +44 -0
- package/dist/routes/blog/index.astro +32 -0
- package/dist/routes/rss.xml.d.ts +2 -0
- package/dist/routes/rss.xml.js +34 -0
- package/dist/routes/rss.xml.ts +44 -0
- package/dist/routes/sitemap-md.xml.d.ts +2 -0
- package/dist/routes/sitemap-md.xml.js +22 -0
- package/dist/routes/sitemap-md.xml.ts +28 -0
- package/dist/routes/sitemap-posts.xml.d.ts +2 -0
- package/dist/routes/sitemap-posts.xml.js +30 -0
- package/dist/routes/sitemap-posts.xml.ts +38 -0
- package/dist/sdk.d.js +0 -0
- package/dist/sdk.d.ts +56 -0
- package/dist/styles/base.css +245 -0
- package/dist/types.d.ts +34 -0
- package/dist/types.js +0 -0
- package/package.json +23 -20
- package/index.ts +0 -65
- package/schema.ts +0 -35
- package/src/components/PageList.astro +0 -131
- package/src/layouts/BlogLayout.astro +0 -39
- package/src/pages/blog/[...slug].astro +0 -40
- package/src/pages/blog/index.astro +0 -38
- package/src/pages/rss.xml.ts +0 -60
- /package/{src → dist}/components/RSSIcon.astro +0 -0
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--accent: #2337ff;
|
|
3
|
+
--accent-dark: #000d8a;
|
|
4
|
+
--black:
|
|
5
|
+
15,
|
|
6
|
+
18,
|
|
7
|
+
25;
|
|
8
|
+
--gray:
|
|
9
|
+
96,
|
|
10
|
+
115,
|
|
11
|
+
159;
|
|
12
|
+
--gray-light:
|
|
13
|
+
229,
|
|
14
|
+
233,
|
|
15
|
+
240;
|
|
16
|
+
--gray-dark:
|
|
17
|
+
34,
|
|
18
|
+
41,
|
|
19
|
+
57;
|
|
20
|
+
--gray-gradient: rgba(var(--gray-light), 50%), #fff;
|
|
21
|
+
--box-shadow:
|
|
22
|
+
0 2px 6px rgba(var(--gray), 25%),
|
|
23
|
+
0 8px 24px rgba(var(--gray), 33%),
|
|
24
|
+
0 16px 32px rgba(var(--gray), 33%);
|
|
25
|
+
}
|
|
26
|
+
body {
|
|
27
|
+
font-family: "Atkinson Hyperlegible", sans-serif;
|
|
28
|
+
margin: 0;
|
|
29
|
+
padding: 0;
|
|
30
|
+
text-align: left;
|
|
31
|
+
background: linear-gradient(var(--gray-gradient)) no-repeat;
|
|
32
|
+
background-size: 100% 600px;
|
|
33
|
+
word-wrap: break-word;
|
|
34
|
+
overflow-wrap: break-word;
|
|
35
|
+
color: rgb(var(--gray-dark));
|
|
36
|
+
font-size: 20px;
|
|
37
|
+
line-height: 1.7;
|
|
38
|
+
}
|
|
39
|
+
main {
|
|
40
|
+
width: 960px;
|
|
41
|
+
max-width: calc(100% - 2em);
|
|
42
|
+
margin: auto;
|
|
43
|
+
padding: 3em 1em;
|
|
44
|
+
}
|
|
45
|
+
h1,
|
|
46
|
+
h2,
|
|
47
|
+
h3,
|
|
48
|
+
h4,
|
|
49
|
+
h5,
|
|
50
|
+
h6 {
|
|
51
|
+
margin: 0 0 0.5rem 0;
|
|
52
|
+
color: rgb(var(--black));
|
|
53
|
+
line-height: 1.2;
|
|
54
|
+
}
|
|
55
|
+
h1 {
|
|
56
|
+
font-size: 3.052em;
|
|
57
|
+
}
|
|
58
|
+
h2 {
|
|
59
|
+
font-size: 2.441em;
|
|
60
|
+
}
|
|
61
|
+
h3 {
|
|
62
|
+
font-size: 1.953em;
|
|
63
|
+
}
|
|
64
|
+
h4 {
|
|
65
|
+
font-size: 1.563em;
|
|
66
|
+
}
|
|
67
|
+
h5 {
|
|
68
|
+
font-size: 1.25em;
|
|
69
|
+
}
|
|
70
|
+
strong,
|
|
71
|
+
b {
|
|
72
|
+
font-weight: 700;
|
|
73
|
+
}
|
|
74
|
+
a {
|
|
75
|
+
color: var(--accent);
|
|
76
|
+
}
|
|
77
|
+
a:hover {
|
|
78
|
+
color: var(--accent);
|
|
79
|
+
}
|
|
80
|
+
p {
|
|
81
|
+
margin-bottom: 1em;
|
|
82
|
+
}
|
|
83
|
+
.prose p {
|
|
84
|
+
margin-bottom: 2em;
|
|
85
|
+
}
|
|
86
|
+
textarea {
|
|
87
|
+
width: 100%;
|
|
88
|
+
font-size: 16px;
|
|
89
|
+
}
|
|
90
|
+
input {
|
|
91
|
+
font-size: 16px;
|
|
92
|
+
}
|
|
93
|
+
table {
|
|
94
|
+
width: 100%;
|
|
95
|
+
}
|
|
96
|
+
img {
|
|
97
|
+
max-width: 100%;
|
|
98
|
+
height: auto;
|
|
99
|
+
border-radius: 8px;
|
|
100
|
+
}
|
|
101
|
+
code {
|
|
102
|
+
padding: 2px 5px;
|
|
103
|
+
background-color: rgb(var(--gray-light));
|
|
104
|
+
border-radius: 2px;
|
|
105
|
+
}
|
|
106
|
+
pre {
|
|
107
|
+
padding: 1.5em;
|
|
108
|
+
border-radius: 8px;
|
|
109
|
+
}
|
|
110
|
+
pre > code {
|
|
111
|
+
all: unset;
|
|
112
|
+
}
|
|
113
|
+
blockquote {
|
|
114
|
+
border-left: 4px solid var(--accent);
|
|
115
|
+
padding: 0 0 0 20px;
|
|
116
|
+
margin: 0px;
|
|
117
|
+
font-size: 1.333em;
|
|
118
|
+
}
|
|
119
|
+
hr {
|
|
120
|
+
border: none;
|
|
121
|
+
border-top: 1px solid rgb(var(--gray-light));
|
|
122
|
+
}
|
|
123
|
+
@media (max-width: 720px) {
|
|
124
|
+
body {
|
|
125
|
+
font-size: 18px;
|
|
126
|
+
}
|
|
127
|
+
main {
|
|
128
|
+
padding: 1em;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
footer {
|
|
132
|
+
padding: 2em 1em 6em 1em;
|
|
133
|
+
background: linear-gradient(var(--gray-gradient)) no-repeat;
|
|
134
|
+
color: rgb(var(--gray));
|
|
135
|
+
text-align: center;
|
|
136
|
+
}
|
|
137
|
+
.social-links {
|
|
138
|
+
display: flex;
|
|
139
|
+
justify-content: center;
|
|
140
|
+
gap: 1em;
|
|
141
|
+
margin-top: 1em;
|
|
142
|
+
}
|
|
143
|
+
.social-links a {
|
|
144
|
+
text-decoration: none;
|
|
145
|
+
color: rgb(var(--gray));
|
|
146
|
+
}
|
|
147
|
+
.social-links a:hover {
|
|
148
|
+
color: rgb(var(--gray-dark));
|
|
149
|
+
}
|
|
150
|
+
.sr-only {
|
|
151
|
+
border: 0;
|
|
152
|
+
padding: 0;
|
|
153
|
+
margin: 0;
|
|
154
|
+
position: absolute !important;
|
|
155
|
+
height: 1px;
|
|
156
|
+
width: 1px;
|
|
157
|
+
overflow: hidden;
|
|
158
|
+
clip: rect(1px 1px 1px 1px);
|
|
159
|
+
clip: rect(1px, 1px, 1px, 1px);
|
|
160
|
+
clip-path: inset(50%);
|
|
161
|
+
white-space: nowrap;
|
|
162
|
+
}
|
|
163
|
+
ul {
|
|
164
|
+
display: flex;
|
|
165
|
+
flex-wrap: wrap;
|
|
166
|
+
gap: 2rem;
|
|
167
|
+
list-style-type: none;
|
|
168
|
+
margin: 0;
|
|
169
|
+
padding: 0;
|
|
170
|
+
}
|
|
171
|
+
ul li {
|
|
172
|
+
width: calc(50% - 1rem);
|
|
173
|
+
}
|
|
174
|
+
ul li * {
|
|
175
|
+
text-decoration: none;
|
|
176
|
+
transition: 0.2s ease;
|
|
177
|
+
}
|
|
178
|
+
ul li:first-child {
|
|
179
|
+
width: 100%;
|
|
180
|
+
margin-bottom: 1rem;
|
|
181
|
+
text-align: center;
|
|
182
|
+
}
|
|
183
|
+
ul li:first-child img {
|
|
184
|
+
width: 100%;
|
|
185
|
+
}
|
|
186
|
+
ul li:first-child .title {
|
|
187
|
+
font-size: 2.369rem;
|
|
188
|
+
}
|
|
189
|
+
ul li img {
|
|
190
|
+
margin-bottom: 0.5rem;
|
|
191
|
+
border-radius: 12px;
|
|
192
|
+
}
|
|
193
|
+
ul li a {
|
|
194
|
+
display: block;
|
|
195
|
+
}
|
|
196
|
+
.title {
|
|
197
|
+
margin: 0;
|
|
198
|
+
color: rgb(var(--black));
|
|
199
|
+
font: bold;
|
|
200
|
+
font-weight: bold;
|
|
201
|
+
line-height: 1;
|
|
202
|
+
display: inline;
|
|
203
|
+
}
|
|
204
|
+
.date {
|
|
205
|
+
margin: 0;
|
|
206
|
+
color: rgb(var(--gray));
|
|
207
|
+
font: normal;
|
|
208
|
+
line-height: normal;
|
|
209
|
+
display: inline;
|
|
210
|
+
}
|
|
211
|
+
.description {
|
|
212
|
+
margin: 0;
|
|
213
|
+
color: rgb(var(--black));
|
|
214
|
+
width: 720px;
|
|
215
|
+
display: -webkit-box;
|
|
216
|
+
-webkit-box-orient: vertical;
|
|
217
|
+
-webkit-line-clamp: 2;
|
|
218
|
+
line-clamp: 2;
|
|
219
|
+
overflow: hidden;
|
|
220
|
+
}
|
|
221
|
+
ul li a:hover span,
|
|
222
|
+
ul li a:hover .date {
|
|
223
|
+
color: rgb(var(--accent));
|
|
224
|
+
}
|
|
225
|
+
ul a:hover img {
|
|
226
|
+
box-shadow: var(--box-shadow);
|
|
227
|
+
}
|
|
228
|
+
@media (max-width: 720px) {
|
|
229
|
+
ul {
|
|
230
|
+
gap: 0.5em;
|
|
231
|
+
}
|
|
232
|
+
ul li {
|
|
233
|
+
width: 100%;
|
|
234
|
+
text-align: center;
|
|
235
|
+
}
|
|
236
|
+
ul li:first-child {
|
|
237
|
+
margin-bottom: 0;
|
|
238
|
+
}
|
|
239
|
+
ul li:first-child .title {
|
|
240
|
+
font-size: 1.563em;
|
|
241
|
+
}
|
|
242
|
+
ul li:first-child .description {
|
|
243
|
+
width: 100%;
|
|
244
|
+
}
|
|
245
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for configuring the StudioCMS Blog.
|
|
3
|
+
*/
|
|
4
|
+
export interface StudioCMSBlogOptions {
|
|
5
|
+
/**
|
|
6
|
+
* Enable sitemap generation
|
|
7
|
+
* @default true
|
|
8
|
+
*/
|
|
9
|
+
sitemap?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Inject routes
|
|
12
|
+
* @default true
|
|
13
|
+
*/
|
|
14
|
+
injectRoutes?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* The configuration for the blog
|
|
17
|
+
*/
|
|
18
|
+
blog?: {
|
|
19
|
+
/**
|
|
20
|
+
* The title of the blog
|
|
21
|
+
*/
|
|
22
|
+
title?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Enable RSS feed
|
|
25
|
+
*/
|
|
26
|
+
enableRSS?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* The route for the blog
|
|
29
|
+
* @default '/blog'
|
|
30
|
+
* @example '/news'
|
|
31
|
+
*/
|
|
32
|
+
route?: string;
|
|
33
|
+
};
|
|
34
|
+
}
|
package/dist/types.js
ADDED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@studiocms/blog",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.8",
|
|
4
4
|
"description": "Add a blog to your StudioCMS project with ease!",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Adam Matthiesen | Jacob Jenkins | Paul Valladares",
|
|
7
|
-
"url": "https://studiocms.
|
|
7
|
+
"url": "https://studiocms.dev"
|
|
8
8
|
},
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
11
|
-
"url": "git+https://github.com/
|
|
11
|
+
"url": "git+https://github.com/withstudiocms/studiocms.git",
|
|
12
|
+
"directory": "packages/studiocms_blog"
|
|
12
13
|
},
|
|
13
14
|
"contributors": [
|
|
14
15
|
"Adammatthiesen",
|
|
@@ -20,7 +21,6 @@
|
|
|
20
21
|
"astro",
|
|
21
22
|
"astrocms",
|
|
22
23
|
"astrodb",
|
|
23
|
-
"astrolicious",
|
|
24
24
|
"astrostudio",
|
|
25
25
|
"astro-integration",
|
|
26
26
|
"astro-studio",
|
|
@@ -33,36 +33,39 @@
|
|
|
33
33
|
"astro-blog",
|
|
34
34
|
"astro-studio-blog",
|
|
35
35
|
"studiocms-blog",
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"studiocms-theme",
|
|
39
|
-
"astro-studiocms-theme"
|
|
36
|
+
"plugin",
|
|
37
|
+
"studiocms-plugin"
|
|
40
38
|
],
|
|
41
|
-
"homepage": "https://studiocms.
|
|
39
|
+
"homepage": "https://studiocms.dev",
|
|
42
40
|
"publishConfig": {
|
|
43
|
-
"access": "public"
|
|
41
|
+
"access": "public",
|
|
42
|
+
"provenance": true
|
|
44
43
|
},
|
|
45
44
|
"sideEffects": false,
|
|
46
45
|
"files": [
|
|
47
|
-
"
|
|
48
|
-
"schema.ts",
|
|
49
|
-
"src"
|
|
46
|
+
"dist"
|
|
50
47
|
],
|
|
51
48
|
"exports": {
|
|
52
|
-
".":
|
|
53
|
-
|
|
49
|
+
".": {
|
|
50
|
+
"types": "./dist/index.d.ts",
|
|
51
|
+
"import": "./dist/index.js"
|
|
52
|
+
}
|
|
54
53
|
},
|
|
55
54
|
"type": "module",
|
|
56
55
|
"dependencies": {
|
|
57
|
-
"@astrojs/rss": "^4.0.
|
|
58
|
-
"astro-
|
|
59
|
-
"@studiocms/core": "0.1.0-beta.7",
|
|
60
|
-
"@studiocms/frontend": "0.1.0-beta.7"
|
|
56
|
+
"@astrojs/rss": "^4.0.11",
|
|
57
|
+
"astro-integration-kit": "^0.18"
|
|
61
58
|
},
|
|
62
59
|
"devDependencies": {
|
|
63
60
|
"@types/node": "^20.14.11"
|
|
64
61
|
},
|
|
65
62
|
"peerDependencies": {
|
|
66
|
-
"astro": "
|
|
63
|
+
"astro": "^5.4.0",
|
|
64
|
+
"vite": "^6.2.0",
|
|
65
|
+
"studiocms": "0.1.0-beta.8"
|
|
66
|
+
},
|
|
67
|
+
"scripts": {
|
|
68
|
+
"build": "build-scripts build 'src/**/*.{ts,css}'",
|
|
69
|
+
"dev": "build-scripts dev 'src/**/*.{ts,css}'"
|
|
67
70
|
}
|
|
68
71
|
}
|
package/index.ts
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { defineStudioCMSPlugin } from '@studiocms/core/lib';
|
|
2
|
-
import defineTheme from 'astro-theme-provider';
|
|
3
|
-
import { name } from './package.json';
|
|
4
|
-
import { studioCMSBlogSchema as schema } from './schema';
|
|
5
|
-
|
|
6
|
-
const studioCMSBlogTheme = defineTheme({
|
|
7
|
-
name,
|
|
8
|
-
schema,
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* User definable options for the StudioCMS Blog Theme
|
|
13
|
-
*/
|
|
14
|
-
export type ATP_ThemeOptions = Parameters<typeof studioCMSBlogTheme>[0];
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* # StudioCMS Blog Theme(Integration)
|
|
18
|
-
* #### Powered by [`astro-theme-provider`](https://github.com/astrolicious/astro-theme-provider) by [Bryce Russell](https://github.com/BryceRussell)
|
|
19
|
-
*
|
|
20
|
-
* This theme provides a Blog Index Page and RSS Feed for your StudioCMS Site as well as route handling for Blog Posts.
|
|
21
|
-
*
|
|
22
|
-
* @example
|
|
23
|
-
* import { defineConfig } from 'astro/config';
|
|
24
|
-
* import db from '@astrojs/db';
|
|
25
|
-
* import studioCMS from 'studiocms';
|
|
26
|
-
* import studioCMSBlog from '@studiocms/blog';
|
|
27
|
-
*
|
|
28
|
-
* // https://astro.build/config
|
|
29
|
-
* export default defineConfig({
|
|
30
|
-
* site: "https://example.com",
|
|
31
|
-
* output: "server",
|
|
32
|
-
* adapter: ...
|
|
33
|
-
* integrations: [
|
|
34
|
-
* db(), // REQUIRED - `@astrojs/db` must be included in the integrations list
|
|
35
|
-
* studioCMS(), // REQUIRED - StudioCMS must be included in the integrations list
|
|
36
|
-
* studioCMSBlog({
|
|
37
|
-
* config: {
|
|
38
|
-
* title: "My StudioCMS Blog",
|
|
39
|
-
* description: "A Simple Blog build with Astro, Astrojs/DB, and StudioCMS.".
|
|
40
|
-
* },
|
|
41
|
-
* }),
|
|
42
|
-
* ],
|
|
43
|
-
* });
|
|
44
|
-
*/
|
|
45
|
-
export function studioCMSBlog(options: ATP_ThemeOptions) {
|
|
46
|
-
let slug: string;
|
|
47
|
-
|
|
48
|
-
if (typeof options?.pages?.['/blog'] === 'string') {
|
|
49
|
-
slug = options.pages['/blog'];
|
|
50
|
-
} else {
|
|
51
|
-
slug = 'blog/';
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
defineStudioCMSPlugin({
|
|
55
|
-
pkgname: name,
|
|
56
|
-
opts: {
|
|
57
|
-
pluginLabel: 'StudioCMS Blog',
|
|
58
|
-
navigationLinks: [{ text: 'Blog', slug: slug }],
|
|
59
|
-
},
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
return studioCMSBlogTheme(options);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export default studioCMSBlog;
|
package/schema.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { z } from 'astro/zod';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* StudioCMS Blog Schema
|
|
5
|
-
*/
|
|
6
|
-
export const studioCMSBlogSchema = z.object({
|
|
7
|
-
/**
|
|
8
|
-
* Title to be used in the RSS Feed.
|
|
9
|
-
*/
|
|
10
|
-
title: z.string().optional(),
|
|
11
|
-
/**
|
|
12
|
-
* Description to be used in the RSS Feed.
|
|
13
|
-
*/
|
|
14
|
-
description: z.string().optional(),
|
|
15
|
-
/**
|
|
16
|
-
* Allows for the configuration of the Blog Index Page.
|
|
17
|
-
*/
|
|
18
|
-
blogIndex: z
|
|
19
|
-
.object({
|
|
20
|
-
/**
|
|
21
|
-
* Title to use for the Blog Index Page.
|
|
22
|
-
*/
|
|
23
|
-
title: z.string().optional().default('Blog'),
|
|
24
|
-
/**
|
|
25
|
-
* Whether to show the RSS Feed URL on the Blog Index Page.
|
|
26
|
-
*/
|
|
27
|
-
showRSSFeed: z.boolean().optional().default(true),
|
|
28
|
-
})
|
|
29
|
-
.optional(),
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* StudioCMS Blog Schema Type
|
|
34
|
-
*/
|
|
35
|
-
export type StudioCMSBlogSchema = z.infer<typeof studioCMSBlogSchema>;
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import { pages } from '@studiocms/blog:context';
|
|
3
|
-
import { FormattedDate } from 'studiocms:components';
|
|
4
|
-
import { pathWithBase } from 'studiocms:helpers';
|
|
5
|
-
import type { pageDataReponse } from 'studiocms:helpers/contentHelper';
|
|
6
|
-
import { CustomImage } from 'studiocms:imageHandler/components';
|
|
7
|
-
|
|
8
|
-
const blogRouteFullPath = pages.get('/blog/[...slug]');
|
|
9
|
-
|
|
10
|
-
function getBlogRoute(slug: string) {
|
|
11
|
-
if (blogRouteFullPath) {
|
|
12
|
-
return blogRouteFullPath.replace('[...slug]', slug);
|
|
13
|
-
}
|
|
14
|
-
return '#';
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
interface Props {
|
|
18
|
-
blogPageList: pageDataReponse[];
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const { blogPageList } = Astro.props;
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
<ul>
|
|
25
|
-
{
|
|
26
|
-
blogPageList.length > 0 && blogPageList.map(({slug, heroImage, title, description, publishedAt}) => (
|
|
27
|
-
<li>
|
|
28
|
-
<a href={pathWithBase(getBlogRoute(slug))}>
|
|
29
|
-
<CustomImage src={heroImage} alt={title} width={720} height={360}/>
|
|
30
|
-
<div>
|
|
31
|
-
<span class="title">{title}</span>
|
|
32
|
-
<span class="date"> <FormattedDate date={publishedAt} /> </span>
|
|
33
|
-
</div>
|
|
34
|
-
|
|
35
|
-
<p class="description">
|
|
36
|
-
{description}
|
|
37
|
-
</p>
|
|
38
|
-
</a>
|
|
39
|
-
</li>
|
|
40
|
-
))
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
{
|
|
44
|
-
blogPageList.length === 0 && <li>No blog posts found</li>
|
|
45
|
-
}
|
|
46
|
-
</ul>
|
|
47
|
-
|
|
48
|
-
<style>
|
|
49
|
-
ul {
|
|
50
|
-
display: flex;
|
|
51
|
-
flex-wrap: wrap;
|
|
52
|
-
gap: 2rem;
|
|
53
|
-
list-style-type: none;
|
|
54
|
-
margin: 0;
|
|
55
|
-
padding: 0;
|
|
56
|
-
}
|
|
57
|
-
ul li {
|
|
58
|
-
width: calc(50% - 1rem);
|
|
59
|
-
}
|
|
60
|
-
ul li * {
|
|
61
|
-
text-decoration: none;
|
|
62
|
-
transition: 0.2s ease;
|
|
63
|
-
}
|
|
64
|
-
ul li:first-child {
|
|
65
|
-
width: 100%;
|
|
66
|
-
margin-bottom: 1rem;
|
|
67
|
-
text-align: center;
|
|
68
|
-
}
|
|
69
|
-
ul li:first-child img {
|
|
70
|
-
width: 100%;
|
|
71
|
-
}
|
|
72
|
-
ul li:first-child .title {
|
|
73
|
-
font-size: 2.369rem;
|
|
74
|
-
}
|
|
75
|
-
ul li img {
|
|
76
|
-
margin-bottom: 0.5rem;
|
|
77
|
-
border-radius: 12px;
|
|
78
|
-
}
|
|
79
|
-
ul li a {
|
|
80
|
-
display: block;
|
|
81
|
-
}
|
|
82
|
-
.title {
|
|
83
|
-
margin: 0;
|
|
84
|
-
color: rgb(var(--black));
|
|
85
|
-
font: bold;
|
|
86
|
-
font-weight: bold;
|
|
87
|
-
line-height: 1;
|
|
88
|
-
display: inline;
|
|
89
|
-
}
|
|
90
|
-
.date {
|
|
91
|
-
margin: 0;
|
|
92
|
-
color: rgb(var(--gray));
|
|
93
|
-
font: normal;
|
|
94
|
-
line-height: normal;
|
|
95
|
-
display: inline;
|
|
96
|
-
}
|
|
97
|
-
.description {
|
|
98
|
-
margin: 0;
|
|
99
|
-
color: rgb(var(--black));
|
|
100
|
-
width: 720px;
|
|
101
|
-
display: -webkit-box;
|
|
102
|
-
-webkit-box-orient: vertical;
|
|
103
|
-
-webkit-line-clamp: 2;
|
|
104
|
-
overflow: hidden;
|
|
105
|
-
}
|
|
106
|
-
ul li a:hover span,
|
|
107
|
-
ul li a:hover .date {
|
|
108
|
-
color: rgb(var(--accent));
|
|
109
|
-
}
|
|
110
|
-
ul a:hover img {
|
|
111
|
-
box-shadow: var(--box-shadow);
|
|
112
|
-
}
|
|
113
|
-
@media (max-width: 720px) {
|
|
114
|
-
ul {
|
|
115
|
-
gap: 0.5em;
|
|
116
|
-
}
|
|
117
|
-
ul li {
|
|
118
|
-
width: 100%;
|
|
119
|
-
text-align: center;
|
|
120
|
-
}
|
|
121
|
-
ul li:first-child {
|
|
122
|
-
margin-bottom: 0;
|
|
123
|
-
}
|
|
124
|
-
ul li:first-child .title {
|
|
125
|
-
font-size: 1.563em;
|
|
126
|
-
}
|
|
127
|
-
ul li:first-child .description {
|
|
128
|
-
width: 100%;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
</style>
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import config from '@studiocms/blog:config';
|
|
3
|
-
import { Layout as FrontLayout } from '@studiocms/frontend/components';
|
|
4
|
-
|
|
5
|
-
interface Props {
|
|
6
|
-
title: string;
|
|
7
|
-
description: string;
|
|
8
|
-
lang?: string | undefined;
|
|
9
|
-
heroImage?: string;
|
|
10
|
-
siteTitle?: string;
|
|
11
|
-
siteDescription?: string;
|
|
12
|
-
pageTitleDelimiter?: string;
|
|
13
|
-
pageDescriptionDelimiter?: string;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const {
|
|
17
|
-
title,
|
|
18
|
-
description,
|
|
19
|
-
heroImage,
|
|
20
|
-
lang,
|
|
21
|
-
pageDescriptionDelimiter,
|
|
22
|
-
pageTitleDelimiter,
|
|
23
|
-
siteDescription = config.description,
|
|
24
|
-
siteTitle,
|
|
25
|
-
} = Astro.props;
|
|
26
|
-
---
|
|
27
|
-
|
|
28
|
-
<FrontLayout
|
|
29
|
-
{title}
|
|
30
|
-
{description}
|
|
31
|
-
{siteTitle}
|
|
32
|
-
{siteDescription}
|
|
33
|
-
{lang}
|
|
34
|
-
{heroImage}
|
|
35
|
-
{pageDescriptionDelimiter}
|
|
36
|
-
{pageTitleDelimiter}
|
|
37
|
-
>
|
|
38
|
-
<slot />
|
|
39
|
-
</FrontLayout>
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import { PostHeader } from '@studiocms:blog/components';
|
|
3
|
-
import { BlogLayout } from '@studiocms:blog/layouts';
|
|
4
|
-
import { contentHelper } from 'studiocms:helpers/contentHelper';
|
|
5
|
-
import { StudioCMSRenderer } from 'studiocms:renderer';
|
|
6
|
-
import { name } from '../../../package.json';
|
|
7
|
-
|
|
8
|
-
// Get the slug from the URL
|
|
9
|
-
const { slug } = Astro.params;
|
|
10
|
-
|
|
11
|
-
// If no slug is provided, redirect to 404
|
|
12
|
-
if (!slug) {
|
|
13
|
-
return new Response(null, { status: 404 });
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
// Fetch the blog post content
|
|
17
|
-
const { id, title, description, heroImage, publishedAt, updatedAt, content } = await contentHelper(
|
|
18
|
-
slug,
|
|
19
|
-
name
|
|
20
|
-
);
|
|
21
|
-
|
|
22
|
-
// If no content is found, redirect to 404
|
|
23
|
-
if (!id) {
|
|
24
|
-
return new Response(null, { status: 404 });
|
|
25
|
-
}
|
|
26
|
-
---
|
|
27
|
-
<BlogLayout {title} {description} {heroImage}>
|
|
28
|
-
<main>
|
|
29
|
-
<article>
|
|
30
|
-
<PostHeader {title} {description} {heroImage} {publishedAt} {updatedAt} />
|
|
31
|
-
<StudioCMSRenderer {content} />
|
|
32
|
-
</article>
|
|
33
|
-
</main>
|
|
34
|
-
</BlogLayout>
|
|
35
|
-
|
|
36
|
-
<style>
|
|
37
|
-
main {
|
|
38
|
-
width: 960px;
|
|
39
|
-
}
|
|
40
|
-
</style>
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
import config from '@studiocms/blog:config';
|
|
3
|
-
import { pages } from '@studiocms/blog:context';
|
|
4
|
-
import { PageList, RSSIcon } from '@studiocms:blog/components';
|
|
5
|
-
import { BlogLayout } from '@studiocms:blog/layouts';
|
|
6
|
-
import { getPageList } from 'studiocms:helpers/contentHelper';
|
|
7
|
-
import { name } from '../../../package.json';
|
|
8
|
-
|
|
9
|
-
// Set the title and description
|
|
10
|
-
const { description: configDescription, blogIndex } = config;
|
|
11
|
-
|
|
12
|
-
const title: string = blogIndex?.title || 'Blog';
|
|
13
|
-
const description: string = configDescription || 'Blog Index';
|
|
14
|
-
const showRSSFeed: boolean = blogIndex?.showRSSFeed || true;
|
|
15
|
-
|
|
16
|
-
// Get all pages
|
|
17
|
-
const pageList = await getPageList();
|
|
18
|
-
|
|
19
|
-
// Get the RSS feed URL
|
|
20
|
-
const rssPath = pages.get('/rss.xml');
|
|
21
|
-
|
|
22
|
-
// Get all blog pages and sort by published date
|
|
23
|
-
const blogPageList = pageList
|
|
24
|
-
.filter((page) => page.package === name)
|
|
25
|
-
.sort((a, b) => Date.parse(b.publishedAt.toString()) - Date.parse(a.publishedAt.toString()));
|
|
26
|
-
---
|
|
27
|
-
<BlogLayout {title} description={description} >
|
|
28
|
-
<main>
|
|
29
|
-
<h1>{title} {showRSSFeed && rssPath && <a href={rssPath}><RSSIcon /></a>}</h1>
|
|
30
|
-
<PageList {blogPageList} />
|
|
31
|
-
</main>
|
|
32
|
-
</BlogLayout>
|
|
33
|
-
|
|
34
|
-
<style>
|
|
35
|
-
main {
|
|
36
|
-
width: 960px;
|
|
37
|
-
}
|
|
38
|
-
</style>
|