astro-accelerator 5.9.21 → 5.10.0
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/astro.config.mjs +2 -0
- package/package.json +3 -3
- package/public/css/main.css +13 -0
- package/src/config.ts +5 -0
- package/src/themes/accelerator/components/AuthorsMini.astro +64 -26
- package/src/themes/accelerator/components/ReadingTime.astro +44 -0
- package/src/themes/accelerator/layouts/Default.astro +102 -83
- package/src/themes/accelerator/utilities/language.json +6 -0
- package/src/themes/accelerator/utilities/reading-time.mjs +18 -0
package/astro.config.mjs
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import mdx from '@astrojs/mdx';
|
|
4
4
|
import remarkDirective from 'remark-directive';
|
|
5
5
|
import { defineConfig } from 'astro/config';
|
|
6
|
+
import { readingTime } from '/src/themes/accelerator/utilities/reading-time.mjs';
|
|
6
7
|
import { defaultLayout } from '/src/themes/accelerator/utilities/default-layout.mjs';
|
|
7
8
|
import {
|
|
8
9
|
attributeMarkdown,
|
|
@@ -19,6 +20,7 @@ export default defineConfig({
|
|
|
19
20
|
remarkDirective,
|
|
20
21
|
attributeMarkdown,
|
|
21
22
|
wrapTables,
|
|
23
|
+
readingTime,
|
|
22
24
|
],
|
|
23
25
|
closeSelfClosing: false,
|
|
24
26
|
extendDefaultPlugins: true,
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "5.
|
|
2
|
+
"version": "5.10.0",
|
|
3
3
|
"author": "Steve Fenton",
|
|
4
4
|
"name": "astro-accelerator",
|
|
5
5
|
"description": "A super-lightweight, accessible, SEO-friendly starter project for Astro",
|
|
@@ -35,8 +35,8 @@
|
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@astrojs/mdx": "^4.3.4",
|
|
37
37
|
"@img/sharp-linux-x64": "^0.34.3",
|
|
38
|
-
"astro": "^5.13.
|
|
39
|
-
"astro-accelerator-utils": "^0.3.
|
|
38
|
+
"astro": "^5.13.5",
|
|
39
|
+
"astro-accelerator-utils": "^0.3.53",
|
|
40
40
|
"cspell": "^8.19.4",
|
|
41
41
|
"csv": "^6.4.1",
|
|
42
42
|
"glob": "^11.0.3",
|
package/public/css/main.css
CHANGED
|
@@ -821,9 +821,22 @@ nav.site-nav h2 {
|
|
|
821
821
|
|
|
822
822
|
.post-meta > .author-info {
|
|
823
823
|
display: flex;
|
|
824
|
+
flex-wrap: wrap;
|
|
824
825
|
align-items: center;
|
|
825
826
|
}
|
|
826
827
|
|
|
828
|
+
.post-meta.mini > .author-info > *:nth-child(n + 3)::before {
|
|
829
|
+
content: '|';
|
|
830
|
+
padding: 0 0.3rem;
|
|
831
|
+
opacity: 0.5;
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
.post-meta.mini > .author-info > .author-image {
|
|
835
|
+
height: 1rem;
|
|
836
|
+
width: 1rem;
|
|
837
|
+
margin: 0 0.3rem 0 0;
|
|
838
|
+
}
|
|
839
|
+
|
|
827
840
|
.post-meta time[itemprop='datePublished'] {
|
|
828
841
|
display: inline-block;
|
|
829
842
|
}
|
package/src/config.ts
CHANGED
|
@@ -4,16 +4,20 @@
|
|
|
4
4
|
import { Accelerator } from 'astro-accelerator-utils';
|
|
5
5
|
import type { Frontmatter } from 'astro-accelerator-utils/types/Frontmatter';
|
|
6
6
|
import { SITE } from '@config';
|
|
7
|
-
import { Translations, Lang } from '@util/Languages'
|
|
7
|
+
import { Translations, Lang } from '@util/Languages';
|
|
8
|
+
import { getImageInfo } from '@util/custom-markdown.mjs';
|
|
9
|
+
import ReadingTime from '@components/ReadingTime.astro';
|
|
8
10
|
|
|
9
11
|
const accelerator = new Accelerator(SITE);
|
|
10
|
-
const stats = new accelerator.statistics(
|
|
12
|
+
const stats = new accelerator.statistics(
|
|
13
|
+
'accelerator/components/AuthorsMini.astro'
|
|
14
|
+
);
|
|
11
15
|
stats.start();
|
|
12
16
|
|
|
13
17
|
// Properties
|
|
14
18
|
type Props = {
|
|
15
|
-
|
|
16
|
-
|
|
19
|
+
lang: string;
|
|
20
|
+
frontmatter: Frontmatter;
|
|
17
21
|
};
|
|
18
22
|
const { lang, frontmatter } = Astro.props satisfies Props;
|
|
19
23
|
|
|
@@ -22,29 +26,63 @@ const _ = Lang(lang);
|
|
|
22
26
|
|
|
23
27
|
// Logic
|
|
24
28
|
const authorList = accelerator.authors.forPost(frontmatter);
|
|
29
|
+
const dateToShow =
|
|
30
|
+
frontmatter.modDate == null ? frontmatter.pubDate : frontmatter.modDate;
|
|
31
|
+
|
|
32
|
+
// Get image info
|
|
33
|
+
const authorImage = authorList?.image?.src
|
|
34
|
+
? getImageInfo(authorList.image.src, 'author-image', SITE.images.authorSize)
|
|
35
|
+
: null;
|
|
25
36
|
|
|
26
37
|
stats.stop();
|
|
27
38
|
---
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
39
|
+
|
|
40
|
+
{
|
|
41
|
+
authorList.writers.length > 0 && (
|
|
42
|
+
<div class="post-meta mini">
|
|
43
|
+
<div class="author-info">
|
|
44
|
+
{authorImage && (
|
|
45
|
+
<img
|
|
46
|
+
srcset={authorImage.srcset}
|
|
47
|
+
sizes={authorImage.sizes}
|
|
48
|
+
src={authorImage.src}
|
|
49
|
+
alt={authorList?.image?.alt}
|
|
50
|
+
class={authorImage.class}
|
|
51
|
+
width={authorImage.metadata?.width}
|
|
52
|
+
height={authorImage.metadata?.height}
|
|
53
|
+
/>
|
|
54
|
+
)}
|
|
55
|
+
{authorList.mainAuthor && (
|
|
56
|
+
<a
|
|
57
|
+
href={
|
|
58
|
+
accelerator.urlFormatter.formatAddress(
|
|
59
|
+
authorList.mainAuthor.url
|
|
60
|
+
) + '1/'
|
|
61
|
+
}
|
|
62
|
+
class="author-name">
|
|
63
|
+
{authorList.mainAuthor.frontmatter.title}
|
|
64
|
+
</a>
|
|
65
|
+
)}
|
|
66
|
+
{authorList.contributors.map((writer) => (
|
|
67
|
+
<a
|
|
68
|
+
href={
|
|
69
|
+
accelerator.urlFormatter.formatAddress(writer.url) +
|
|
70
|
+
'1/'
|
|
71
|
+
}
|
|
72
|
+
class="contributor-name">
|
|
73
|
+
{writer.frontmatter.title}
|
|
74
|
+
</a>
|
|
75
|
+
))}
|
|
76
|
+
<time
|
|
77
|
+
class="post-date"
|
|
78
|
+
datetime={dateToShow.toString()}
|
|
79
|
+
set:html={accelerator.dateFormatter.formatShortDate(
|
|
80
|
+
dateToShow,
|
|
81
|
+
lang
|
|
82
|
+
)}
|
|
83
|
+
/>
|
|
84
|
+
<ReadingTime lang={lang} frontmatter={frontmatter} />
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
)
|
|
50
88
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
// warning: This file is overwritten by Astro Accelerator
|
|
3
|
+
|
|
4
|
+
import { Accelerator } from 'astro-accelerator-utils';
|
|
5
|
+
import type { Frontmatter } from 'astro-accelerator-utils/types/Frontmatter';
|
|
6
|
+
import { SITE } from '@config';
|
|
7
|
+
import { Translations, Lang } from '@util/Languages';
|
|
8
|
+
|
|
9
|
+
const accelerator = new Accelerator(SITE);
|
|
10
|
+
const stats = new accelerator.statistics(
|
|
11
|
+
'accelerator/components/ReadingTime.astro'
|
|
12
|
+
);
|
|
13
|
+
stats.start();
|
|
14
|
+
|
|
15
|
+
// Properties
|
|
16
|
+
type Props = {
|
|
17
|
+
lang: string;
|
|
18
|
+
frontmatter: Frontmatter;
|
|
19
|
+
};
|
|
20
|
+
const { lang, frontmatter } = Astro.props satisfies Props;
|
|
21
|
+
|
|
22
|
+
// Language
|
|
23
|
+
const _ = Lang(lang);
|
|
24
|
+
|
|
25
|
+
// Logic
|
|
26
|
+
const readingTimeText =
|
|
27
|
+
frontmatter?.readingTime === 1
|
|
28
|
+
? _(Translations.post.reading_time_one_minute).replace(
|
|
29
|
+
'{n}',
|
|
30
|
+
frontmatter.readingTime
|
|
31
|
+
)
|
|
32
|
+
: _(Translations.post.reading_time_many_minutes).replace(
|
|
33
|
+
'{n}',
|
|
34
|
+
frontmatter.readingTime
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
stats.stop();
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
{
|
|
41
|
+
frontmatter?.readingTime && (
|
|
42
|
+
<span class="reading-time" set:html={readingTimeText} />
|
|
43
|
+
)
|
|
44
|
+
}
|
|
@@ -1,116 +1,135 @@
|
|
|
1
1
|
---
|
|
2
2
|
// warning: This file is overwritten by Astro Accelerator
|
|
3
3
|
|
|
4
|
-
import { Accelerator, PostFiltering } from
|
|
5
|
-
import type { Frontmatter } from
|
|
6
|
-
import { getImageInfo } from
|
|
7
|
-
import { SITE } from
|
|
8
|
-
import Head from
|
|
9
|
-
import Header from
|
|
10
|
-
import Footer from
|
|
11
|
-
import Copyright from
|
|
12
|
-
import SkipLinks from
|
|
13
|
-
import Breadcrumbs from
|
|
14
|
-
import Navigation from
|
|
15
|
-
import TableOfContents from
|
|
16
|
-
import Authors from
|
|
17
|
-
import
|
|
18
|
-
import
|
|
4
|
+
import { Accelerator, PostFiltering } from 'astro-accelerator-utils';
|
|
5
|
+
import type { Frontmatter } from 'astro-accelerator-utils/types/Frontmatter';
|
|
6
|
+
import { getImageInfo } from '@util/custom-markdown.mjs';
|
|
7
|
+
import { SITE } from '@config';
|
|
8
|
+
import Head from '@components/HtmlHead.astro';
|
|
9
|
+
import Header from '@components/Header.astro';
|
|
10
|
+
import Footer from '@components/Footer.astro';
|
|
11
|
+
import Copyright from '@components/Copyright.astro';
|
|
12
|
+
import SkipLinks from '@components/SkipLinks.astro';
|
|
13
|
+
import Breadcrumbs from '@components/Breadcrumbs.astro';
|
|
14
|
+
import Navigation from '@components/Navigation.astro';
|
|
15
|
+
import TableOfContents from '@components/TableOfContents.astro';
|
|
16
|
+
import Authors from '@components/Authors.astro';
|
|
17
|
+
import AuthorsMini from '@components/AuthorsMini.astro';
|
|
18
|
+
import Taxonomy from '@components/Taxonomy.astro';
|
|
19
|
+
import Related from '@components/Related.astro';
|
|
19
20
|
|
|
20
21
|
const accelerator = new Accelerator(SITE);
|
|
21
|
-
const stats = new accelerator.statistics(
|
|
22
|
+
const stats = new accelerator.statistics('accelerator/layouts/Default.astro');
|
|
22
23
|
stats.start();
|
|
23
24
|
|
|
24
25
|
type Props = {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
frontmatter: Frontmatter;
|
|
27
|
+
headings: { depth: number; slug: string; text: string }[];
|
|
28
|
+
breadcrumbs?: { url: string; title: string; ariaCurrent?: string }[] | null;
|
|
28
29
|
};
|
|
29
|
-
const { frontmatter, headings, breadcrumbs } =
|
|
30
|
+
const { frontmatter, headings, breadcrumbs, data } =
|
|
31
|
+
Astro.props satisfies Props;
|
|
30
32
|
|
|
31
33
|
const lang = frontmatter.lang ?? SITE.default.lang;
|
|
32
34
|
const textDirection = frontmatter.dir ?? SITE.default.dir;
|
|
33
35
|
|
|
34
36
|
// Logic
|
|
35
37
|
const metaImage = frontmatter.bannerImage
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
? getImageInfo(frontmatter.bannerImage.src, '', SITE.images.contentSize)
|
|
39
|
+
: null;
|
|
38
40
|
|
|
39
41
|
const title = await accelerator.markdown.getInlineHtmlFrom(
|
|
40
|
-
|
|
42
|
+
frontmatter.title ?? SITE.title
|
|
41
43
|
);
|
|
42
44
|
const subtitle = frontmatter.subtitle
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
? await accelerator.markdown.getInlineHtmlFrom(frontmatter.subtitle)
|
|
46
|
+
: null;
|
|
45
47
|
|
|
46
48
|
const site_url = SITE.url;
|
|
47
49
|
const site_features = SITE.featureFlags;
|
|
48
50
|
const search =
|
|
49
|
-
|
|
51
|
+
accelerator.posts.all().filter(PostFiltering.isSearch).shift() ?? null;
|
|
50
52
|
const searchUrl = search && accelerator.urlFormatter.formatAddress(search.url);
|
|
51
53
|
const isSearchPage =
|
|
52
|
-
|
|
54
|
+
accelerator.urlFormatter.formatAddress(Astro.url.pathname) === searchUrl;
|
|
53
55
|
const showSearch = !isSearchPage;
|
|
54
56
|
|
|
55
57
|
stats.stop();
|
|
56
58
|
---
|
|
57
59
|
|
|
58
60
|
<html dir={textDirection} lang={lang} class="initial">
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
61
|
+
<Head frontmatter={frontmatter} headings={headings} lang={lang} />
|
|
62
|
+
<body>
|
|
63
|
+
<SkipLinks frontmatter={frontmatter} headings={headings} lang={lang} />
|
|
64
|
+
<Header
|
|
65
|
+
frontmatter={frontmatter}
|
|
66
|
+
headings={headings}
|
|
67
|
+
lang={lang}
|
|
68
|
+
showSearch={showSearch}
|
|
69
|
+
/>
|
|
70
|
+
<Breadcrumbs
|
|
71
|
+
frontmatter={frontmatter}
|
|
72
|
+
headings={headings}
|
|
73
|
+
lang={lang}
|
|
74
|
+
breadcrumbs={breadcrumbs}
|
|
75
|
+
/>
|
|
76
|
+
<div class="content-group">
|
|
77
|
+
<main id="site-main">
|
|
78
|
+
<article itemscope itemtype="https://schema.org/Article">
|
|
79
|
+
<header>
|
|
80
|
+
<h1 itemprop="name headline">
|
|
81
|
+
<Fragment set:html={title} />
|
|
82
|
+
</h1>
|
|
83
|
+
{
|
|
84
|
+
subtitle && (
|
|
85
|
+
<p>
|
|
86
|
+
<Fragment set:html={subtitle} />
|
|
87
|
+
</p>
|
|
88
|
+
)
|
|
89
|
+
}
|
|
90
|
+
</header>
|
|
91
|
+
<div
|
|
92
|
+
class="page-content anim-show-parent"
|
|
93
|
+
itemprop="articleBody">
|
|
94
|
+
<AuthorsMini frontmatter={frontmatter} lang={lang} />
|
|
95
|
+
<TableOfContents
|
|
96
|
+
frontmatter={frontmatter}
|
|
97
|
+
headings={headings}
|
|
98
|
+
lang={lang}
|
|
99
|
+
/>
|
|
100
|
+
<slot />
|
|
101
|
+
<Authors frontmatter={frontmatter} lang={lang} />
|
|
102
|
+
<Taxonomy frontmatter={frontmatter} lang={lang} />
|
|
103
|
+
<Related
|
|
104
|
+
frontmatter={frontmatter}
|
|
105
|
+
headings={headings}
|
|
106
|
+
lang={lang}
|
|
107
|
+
/>
|
|
108
|
+
{
|
|
109
|
+
metaImage && (
|
|
110
|
+
<meta
|
|
111
|
+
itemprop="image"
|
|
112
|
+
content={metaImage.src}
|
|
113
|
+
/>
|
|
114
|
+
)
|
|
115
|
+
}
|
|
116
|
+
</div>
|
|
117
|
+
</article>
|
|
118
|
+
</main>
|
|
119
|
+
<Navigation lang={lang} />
|
|
120
|
+
</div>
|
|
121
|
+
<Footer frontmatter={frontmatter} headings={headings} lang={lang}>
|
|
122
|
+
<Copyright
|
|
123
|
+
frontmatter={frontmatter}
|
|
124
|
+
headings={headings}
|
|
125
|
+
lang={lang}
|
|
92
126
|
/>
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
{metaImage && <meta itemprop="image" content={metaImage.src} />}
|
|
102
|
-
</div>
|
|
103
|
-
</article>
|
|
104
|
-
</main>
|
|
105
|
-
<Navigation lang={lang} />
|
|
106
|
-
</div>
|
|
107
|
-
<Footer frontmatter={frontmatter} headings={headings} lang={lang}>
|
|
108
|
-
<Copyright frontmatter={frontmatter} headings={headings} lang={lang} />
|
|
109
|
-
</Footer>
|
|
110
|
-
<script define:vars={{ site_url, site_features }}>
|
|
111
|
-
window.site_url = site_url;
|
|
112
|
-
window.site_features = site_features;
|
|
113
|
-
</script>
|
|
114
|
-
<script src={SITE.subfolder + "/js/main.js"} type="module" async></script>
|
|
115
|
-
</body>
|
|
127
|
+
</Footer>
|
|
128
|
+
<script define:vars={{ site_url, site_features }}>
|
|
129
|
+
window.site_url = site_url;
|
|
130
|
+
window.site_features = site_features;
|
|
131
|
+
</script>
|
|
132
|
+
<script src={SITE.subfolder + '/js/main.js'} type="module" async
|
|
133
|
+
></script>
|
|
134
|
+
</body>
|
|
116
135
|
</html>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** @format */
|
|
2
|
+
|
|
3
|
+
import { toString } from 'mdast-util-to-string';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Remark plugin for calculating reading time
|
|
7
|
+
*/
|
|
8
|
+
export function readingTime() {
|
|
9
|
+
return function (tree, { data }) {
|
|
10
|
+
const wordsPerMinute = 200;
|
|
11
|
+
const textOnPage = toString(tree);
|
|
12
|
+
const readingTime = Math.ceil(
|
|
13
|
+
textOnPage.split(' ').length / wordsPerMinute
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
data.astro.frontmatter.readingTime = readingTime;
|
|
17
|
+
};
|
|
18
|
+
}
|