astro-accelerator-utils 0.1.18 → 0.1.19
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/index.d.mts +2 -3
- package/index.mjs +3 -5
- package/lib/v1/taxonomy.d.mts +62 -0
- package/lib/v1/taxonomy.mjs +145 -0
- package/package.json +1 -1
- package/types/Taxonomy.d.ts +1 -1
- package/lib/postPaging.d.mts +0 -13
- package/lib/postPaging.mjs +0 -77
- package/lib/taxonomy.d.mts +0 -25
- package/lib/taxonomy.mjs +0 -129
- package/types/Link.d.ts +0 -6
package/index.d.mts
CHANGED
|
@@ -5,10 +5,9 @@ import { Markdown } from "./lib/v1/markdown.mjs";
|
|
|
5
5
|
import { Navigation } from "./lib/v1/navigation.mjs";
|
|
6
6
|
import { Paging } from "./lib/v1/paging.mjs";
|
|
7
7
|
import { Posts } from "./lib/v1/posts.mjs";
|
|
8
|
+
import { Taxonomy } from "./lib/v1/taxonomy.mjs";
|
|
8
9
|
import { UrlFormatter } from "./lib/v1/urls.mjs";
|
|
9
10
|
import * as PostFiltering from "./lib/postFiltering.mjs";
|
|
10
11
|
import * as PostOrdering from "./lib/postOrdering.mjs";
|
|
11
|
-
import * as PostPaging from "./lib/postPaging.mjs";
|
|
12
12
|
import * as FooterMenu from "./lib/footerMenu.mjs";
|
|
13
|
-
|
|
14
|
-
export { Authors, Cache, DateFormatter, Markdown, Navigation, Paging, Posts, UrlFormatter, PostFiltering, PostOrdering, PostPaging, FooterMenu, Taxonomy };
|
|
13
|
+
export { Authors, Cache, DateFormatter, Markdown, Navigation, Paging, Posts, Taxonomy, UrlFormatter, PostFiltering, PostOrdering, FooterMenu };
|
package/index.mjs
CHANGED
|
@@ -5,13 +5,12 @@ import { Markdown } from './lib/v1/markdown.mjs';
|
|
|
5
5
|
import { Navigation } from './lib/v1/navigation.mjs';
|
|
6
6
|
import { Paging } from './lib/v1/paging.mjs';
|
|
7
7
|
import { Posts } from './lib/v1/posts.mjs';
|
|
8
|
+
import { Taxonomy } from './lib/v1/taxonomy.mjs';
|
|
8
9
|
import { UrlFormatter } from './lib/v1/urls.mjs';
|
|
9
10
|
|
|
10
11
|
import * as PostFiltering from './lib/postFiltering.mjs';
|
|
11
12
|
import * as PostOrdering from './lib/postOrdering.mjs';
|
|
12
|
-
import * as PostPaging from './lib/postPaging.mjs';
|
|
13
13
|
import * as FooterMenu from './lib/footerMenu.mjs';
|
|
14
|
-
import * as Taxonomy from './lib/taxonomy.mjs';
|
|
15
14
|
|
|
16
15
|
export {
|
|
17
16
|
Authors,
|
|
@@ -21,10 +20,9 @@ export {
|
|
|
21
20
|
Navigation,
|
|
22
21
|
Paging,
|
|
23
22
|
Posts,
|
|
23
|
+
Taxonomy,
|
|
24
24
|
UrlFormatter,
|
|
25
25
|
PostFiltering,
|
|
26
26
|
PostOrdering,
|
|
27
|
-
|
|
28
|
-
FooterMenu,
|
|
29
|
-
Taxonomy
|
|
27
|
+
FooterMenu
|
|
30
28
|
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef { import("./cache.mjs").Cache } Cache
|
|
3
|
+
* @typedef { import("./posts.mjs").Posts } Posts
|
|
4
|
+
* @typedef { import("./urls.mjs").UrlFormatter } UrlFormatter
|
|
5
|
+
* @typedef { import("../../types/Site").Site } Site
|
|
6
|
+
* @typedef { import("../../types/Taxonomy").TaxonomyList } TaxonomyList
|
|
7
|
+
* @typedef { import("../../types/Taxonomy").TaxonomyEntry } TaxonomyEntry
|
|
8
|
+
* @typedef { import("../../types/Taxonomy").TaxonomyLinks } TaxonomyLinks
|
|
9
|
+
* @typedef { import("../../types/Astro").MarkdownInstance } MarkdownInstance
|
|
10
|
+
*/
|
|
11
|
+
export class Taxonomy {
|
|
12
|
+
/**
|
|
13
|
+
* Constructor
|
|
14
|
+
* @param {Cache} cache
|
|
15
|
+
* @param {Posts} posts
|
|
16
|
+
* @param {UrlFormatter} urlFormatter
|
|
17
|
+
*/
|
|
18
|
+
constructor(cache: Cache, posts: Posts, urlFormatter: UrlFormatter);
|
|
19
|
+
cache: import("./cache.mjs").Cache;
|
|
20
|
+
posts: import("./posts.mjs").Posts;
|
|
21
|
+
urlFormatter: import("./urls.mjs").UrlFormatter;
|
|
22
|
+
/**
|
|
23
|
+
*
|
|
24
|
+
* @returns {TaxonomyList}
|
|
25
|
+
*/
|
|
26
|
+
all(): TaxonomyList;
|
|
27
|
+
/**
|
|
28
|
+
*
|
|
29
|
+
* @param {any} translations
|
|
30
|
+
* @param {(entry: any) => string} lang
|
|
31
|
+
* @param {string} subfolder
|
|
32
|
+
* @returns {TaxonomyLinks}
|
|
33
|
+
*/
|
|
34
|
+
links(translations: any, lang: (entry: any) => string, subfolder: string): TaxonomyLinks;
|
|
35
|
+
/**
|
|
36
|
+
*
|
|
37
|
+
* @returns {TaxonomyList}
|
|
38
|
+
*/
|
|
39
|
+
getTaxonomy(): TaxonomyList;
|
|
40
|
+
/**
|
|
41
|
+
* Sorts taxonomy entries by title
|
|
42
|
+
* @param {TaxonomyEntry} a
|
|
43
|
+
* @param {TaxonomyEntry} b
|
|
44
|
+
* @returns
|
|
45
|
+
*/
|
|
46
|
+
sortByTitle(a: TaxonomyEntry, b: TaxonomyEntry): 0 | 1 | -1;
|
|
47
|
+
/**
|
|
48
|
+
* Sorts taxonomy entries by title
|
|
49
|
+
* @param {TaxonomyEntry} a
|
|
50
|
+
* @param {TaxonomyEntry} b
|
|
51
|
+
* @returns
|
|
52
|
+
*/
|
|
53
|
+
sortByVolume(a: TaxonomyEntry, b: TaxonomyEntry): number;
|
|
54
|
+
}
|
|
55
|
+
export type Cache = import("./cache.mjs").Cache;
|
|
56
|
+
export type Posts = import("./posts.mjs").Posts;
|
|
57
|
+
export type UrlFormatter = import("./urls.mjs").UrlFormatter;
|
|
58
|
+
export type Site = import("../../types/Site").Site;
|
|
59
|
+
export type TaxonomyList = import("../../types/Taxonomy").TaxonomyList;
|
|
60
|
+
export type TaxonomyEntry = import("../../types/Taxonomy").TaxonomyEntry;
|
|
61
|
+
export type TaxonomyLinks = import("../../types/Taxonomy").TaxonomyLinks;
|
|
62
|
+
export type MarkdownInstance = import("../../types/Astro").MarkdownInstance;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import * as PostFiltering from '../postFiltering.mjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @typedef { import("./cache.mjs").Cache } Cache
|
|
5
|
+
* @typedef { import("./posts.mjs").Posts } Posts
|
|
6
|
+
* @typedef { import("./urls.mjs").UrlFormatter } UrlFormatter
|
|
7
|
+
* @typedef { import("../../types/Site").Site } Site
|
|
8
|
+
* @typedef { import("../../types/Taxonomy").TaxonomyList } TaxonomyList
|
|
9
|
+
* @typedef { import("../../types/Taxonomy").TaxonomyEntry } TaxonomyEntry
|
|
10
|
+
* @typedef { import("../../types/Taxonomy").TaxonomyLinks } TaxonomyLinks
|
|
11
|
+
* @typedef { import("../../types/Astro").MarkdownInstance } MarkdownInstance
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export class Taxonomy {
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Constructor
|
|
18
|
+
* @param {Cache} cache
|
|
19
|
+
* @param {Posts} posts
|
|
20
|
+
* @param {UrlFormatter} urlFormatter
|
|
21
|
+
*/
|
|
22
|
+
constructor(cache, posts, urlFormatter) {
|
|
23
|
+
this.cache = cache;
|
|
24
|
+
this.posts = posts;
|
|
25
|
+
this.urlFormatter = urlFormatter;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
*
|
|
30
|
+
* @returns {TaxonomyList}
|
|
31
|
+
*/
|
|
32
|
+
all() {
|
|
33
|
+
const taxonomy = this.cache.get('v1_taxonomy.all', () => this.getTaxonomy());
|
|
34
|
+
return taxonomy;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
*
|
|
39
|
+
* @param {any} translations
|
|
40
|
+
* @param {(entry: any) => string} lang
|
|
41
|
+
* @param {string} subfolder
|
|
42
|
+
* @returns {TaxonomyLinks}
|
|
43
|
+
*/
|
|
44
|
+
links(translations, lang, subfolder) {
|
|
45
|
+
const category = lang(translations.articles.category) ?? 'category';
|
|
46
|
+
const categoryLink = `${subfolder}/${category}/`;
|
|
47
|
+
|
|
48
|
+
const tag = lang(translations.articles.tag) ?? 'tag';
|
|
49
|
+
const tagLink = `${subfolder}/${tag}/`;
|
|
50
|
+
|
|
51
|
+
return {
|
|
52
|
+
tag: tag,
|
|
53
|
+
category: category,
|
|
54
|
+
getCategoryLink: (category) => {
|
|
55
|
+
return this.urlFormatter.addSlashToAddress(categoryLink + category.toLowerCase().replace(/ /g, '-') + '/1/');
|
|
56
|
+
},
|
|
57
|
+
getTagLink: (tag) => {
|
|
58
|
+
return this.urlFormatter.addSlashToAddress(tagLink + tag.toLowerCase().replace(/ /g, '-') + '/1/');
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
*
|
|
65
|
+
* @returns {TaxonomyList}
|
|
66
|
+
*/
|
|
67
|
+
getTaxonomy() {
|
|
68
|
+
/** @type {MarkdownInstance[]} */
|
|
69
|
+
const allPages = this.posts.all().filter(PostFiltering.isListable);
|
|
70
|
+
|
|
71
|
+
/** @type {{ [key: string]: number }} */
|
|
72
|
+
const tags = {};
|
|
73
|
+
|
|
74
|
+
/** @type {{ [key: string]: number }} */
|
|
75
|
+
const cats = {};
|
|
76
|
+
|
|
77
|
+
// Get taxonomy and counts
|
|
78
|
+
allPages.forEach((p) => {
|
|
79
|
+
p.frontmatter.tags && (p.frontmatter.tags).forEach(t => {
|
|
80
|
+
tags[t] = (tags[t] ?? 0) + 1;
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
p.frontmatter.categories && (p.frontmatter.categories).forEach(c => {
|
|
84
|
+
cats[c] = (cats[c] ?? 0) + 1;
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// Map into the taxonomy
|
|
89
|
+
const taxonomy = {
|
|
90
|
+
tags: Object.keys(tags).sort().map(x => {
|
|
91
|
+
return {
|
|
92
|
+
title: x,
|
|
93
|
+
count: tags[x]
|
|
94
|
+
};
|
|
95
|
+
}),
|
|
96
|
+
topTags: [],
|
|
97
|
+
categories: Object.keys(cats).sort().map(x => {
|
|
98
|
+
return {
|
|
99
|
+
title: x,
|
|
100
|
+
count: cats[x]
|
|
101
|
+
};
|
|
102
|
+
})
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
// Get a list of "top tags" by usage count
|
|
106
|
+
const length = Math.min(taxonomy.categories.length, taxonomy.tags.length);
|
|
107
|
+
taxonomy.topTags = taxonomy.tags
|
|
108
|
+
.sort(this.sortByVolume)
|
|
109
|
+
.slice(0, length);
|
|
110
|
+
|
|
111
|
+
taxonomy.categories = taxonomy.categories.sort(this.sortByTitle);
|
|
112
|
+
taxonomy.tags = taxonomy.tags.sort(this.sortByTitle);
|
|
113
|
+
taxonomy.topTags = taxonomy.topTags.sort(this.sortByTitle);
|
|
114
|
+
|
|
115
|
+
return taxonomy;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Sorts taxonomy entries by title
|
|
120
|
+
* @param {TaxonomyEntry} a
|
|
121
|
+
* @param {TaxonomyEntry} b
|
|
122
|
+
* @returns
|
|
123
|
+
*/
|
|
124
|
+
sortByTitle(a, b) {
|
|
125
|
+
if (a.title < b.title) {
|
|
126
|
+
return -1;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if (a.title > b.title) {
|
|
130
|
+
return 1;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return 0;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Sorts taxonomy entries by title
|
|
138
|
+
* @param {TaxonomyEntry} a
|
|
139
|
+
* @param {TaxonomyEntry} b
|
|
140
|
+
* @returns
|
|
141
|
+
*/
|
|
142
|
+
sortByVolume(a, b) {
|
|
143
|
+
return b.count - a.count;
|
|
144
|
+
}
|
|
145
|
+
}
|
package/package.json
CHANGED
package/types/Taxonomy.d.ts
CHANGED
package/lib/postPaging.d.mts
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @typedef { import("../types/Link").Link } Link
|
|
3
|
-
*/
|
|
4
|
-
/**
|
|
5
|
-
* Provides a list of paging links, 1 ... 3 4 5 ... 7
|
|
6
|
-
* @param {number} limit
|
|
7
|
-
* @param {number} numberOfPages
|
|
8
|
-
* @param {number} currentPage
|
|
9
|
-
* @param {string} url
|
|
10
|
-
* @returns {Link[]}
|
|
11
|
-
*/
|
|
12
|
-
export function getPageLinks(limit: number, numberOfPages: number, currentPage: number, url: string): Link[];
|
|
13
|
-
export type Link = import("../types/Link").Link;
|
package/lib/postPaging.mjs
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @typedef { import("../types/Link").Link } Link
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Provides a list of paging links, 1 ... 3 4 5 ... 7
|
|
7
|
-
* @param {number} limit
|
|
8
|
-
* @param {number} numberOfPages
|
|
9
|
-
* @param {number} currentPage
|
|
10
|
-
* @param {string} url
|
|
11
|
-
* @returns {Link[]}
|
|
12
|
-
*/
|
|
13
|
-
export function getPageLinks(limit, numberOfPages, currentPage, url) {
|
|
14
|
-
/** @type {Link[]} */
|
|
15
|
-
const pageLinks = [];
|
|
16
|
-
|
|
17
|
-
let start = 0;
|
|
18
|
-
let end = numberOfPages;
|
|
19
|
-
|
|
20
|
-
if (numberOfPages > limit) {
|
|
21
|
-
start = (currentPage - (limit - 1) / 2) - 1;
|
|
22
|
-
if (start < 0) {
|
|
23
|
-
start = 0;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
end = (start + limit);
|
|
27
|
-
if (end > numberOfPages) {
|
|
28
|
-
end = numberOfPages;
|
|
29
|
-
start = numberOfPages - limit;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (start == 1) {
|
|
34
|
-
pageLinks.push({
|
|
35
|
-
title: '1',
|
|
36
|
-
url: url.replace('/' + currentPage, '/' + 1),
|
|
37
|
-
ariaCurrent: false,
|
|
38
|
-
class: ''
|
|
39
|
-
});
|
|
40
|
-
} else if (start > 1) {
|
|
41
|
-
pageLinks.push({
|
|
42
|
-
title: '1',
|
|
43
|
-
url: url.replace('/' + currentPage, '/' + 1),
|
|
44
|
-
ariaCurrent: false,
|
|
45
|
-
class: 'paging-collapse-after'
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
for (let i = start; i < end; i++) {
|
|
50
|
-
const userPage = i + 1;
|
|
51
|
-
pageLinks.push({
|
|
52
|
-
title: userPage.toString(),
|
|
53
|
-
url: url.replace('/' + currentPage, '/' + userPage),
|
|
54
|
-
ariaCurrent: userPage == currentPage ? 'page' : false,
|
|
55
|
-
class: ''
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (end < (numberOfPages - 1)) {
|
|
60
|
-
pageLinks.push({
|
|
61
|
-
title: numberOfPages.toString(),
|
|
62
|
-
url: url.replace('/' + currentPage, '/' + numberOfPages),
|
|
63
|
-
ariaCurrent: false,
|
|
64
|
-
class: 'paging-collapse-before'
|
|
65
|
-
});
|
|
66
|
-
} else if (end < numberOfPages) {
|
|
67
|
-
pageLinks.push({
|
|
68
|
-
title: numberOfPages.toString(),
|
|
69
|
-
url: url.replace('/' + currentPage, '/' + numberOfPages),
|
|
70
|
-
ariaCurrent: false,
|
|
71
|
-
class: ''
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
return pageLinks;
|
|
76
|
-
}
|
|
77
|
-
|
package/lib/taxonomy.d.mts
DELETED
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
*
|
|
3
|
-
* @param {TaxonomyEntry} a
|
|
4
|
-
* @param {TaxonomyEntry} b
|
|
5
|
-
* @returns
|
|
6
|
-
*/
|
|
7
|
-
export function sortByTitle(a: TaxonomyEntry, b: TaxonomyEntry): 0 | 1 | -1;
|
|
8
|
-
/**
|
|
9
|
-
*
|
|
10
|
-
* @param {any} translations
|
|
11
|
-
* @param {(entry: any) => string} lang
|
|
12
|
-
* @param {Site} site
|
|
13
|
-
* @returns {TaxonomyLinks}
|
|
14
|
-
*/
|
|
15
|
-
export function taxonomyLinks(translations: any, lang: (entry: any) => string, site: Site): TaxonomyLinks;
|
|
16
|
-
/**
|
|
17
|
-
*
|
|
18
|
-
* @returns {Promise<Taxonomy>}
|
|
19
|
-
*/
|
|
20
|
-
export function getTaxonomy(): Promise<Taxonomy>;
|
|
21
|
-
export type Site = import("../types/Site").Site;
|
|
22
|
-
export type Taxonomy = import("../types/Taxonomy").Taxonomy;
|
|
23
|
-
export type TaxonomyEntry = import("../types/Taxonomy").TaxonomyEntry;
|
|
24
|
-
export type TaxonomyLinks = import("../types/Taxonomy").TaxonomyLinks;
|
|
25
|
-
export type MarkdownInstance = import("../types/Astro").MarkdownInstance;
|
package/lib/taxonomy.mjs
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import { Cache } from './v1/cache.mjs';
|
|
2
|
-
import { Posts } from './v1/posts.mjs';
|
|
3
|
-
import { UrlFormatter } from './v1/urls.mjs';
|
|
4
|
-
import * as PostFiltering from './postFiltering.mjs';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @typedef { import("../types/Site").Site } Site
|
|
8
|
-
* @typedef { import("../types/Taxonomy").Taxonomy } Taxonomy
|
|
9
|
-
* @typedef { import("../types/Taxonomy").TaxonomyEntry } TaxonomyEntry
|
|
10
|
-
* @typedef { import("../types/Taxonomy").TaxonomyLinks } TaxonomyLinks
|
|
11
|
-
* @typedef { import("../types/Astro").MarkdownInstance } MarkdownInstance
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
const cache = new Cache(200);
|
|
15
|
-
const posts = new Posts(cache);
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
*
|
|
19
|
-
* @param {TaxonomyEntry} a
|
|
20
|
-
* @param {TaxonomyEntry} b
|
|
21
|
-
* @returns
|
|
22
|
-
*/
|
|
23
|
-
export function sortByTitle (a, b) {
|
|
24
|
-
if ( a.title < b.title ){
|
|
25
|
-
return -1;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
if ( a.title > b.title ){
|
|
29
|
-
return 1;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return 0;
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
*
|
|
37
|
-
* @param {any} translations
|
|
38
|
-
* @param {(entry: any) => string} lang
|
|
39
|
-
* @param {Site} site
|
|
40
|
-
* @returns {TaxonomyLinks}
|
|
41
|
-
*/
|
|
42
|
-
export function taxonomyLinks(translations, lang, site) {
|
|
43
|
-
const urlFormatter = new UrlFormatter(site.url);
|
|
44
|
-
const category = lang(translations.articles.category) ?? 'category';
|
|
45
|
-
const categoryLink = `${site.subfolder}/${category}/`;
|
|
46
|
-
|
|
47
|
-
const tag = lang(translations.articles.tag) ?? 'category';
|
|
48
|
-
const tagLink = `${site.subfolder}/${tag}/`;
|
|
49
|
-
|
|
50
|
-
return {
|
|
51
|
-
tag: tag,
|
|
52
|
-
category: category,
|
|
53
|
-
getCategoryLink: (category) => {
|
|
54
|
-
return urlFormatter.addSlashToAddress(categoryLink + category.toLowerCase().replace(/ /g, '-') + '/1/');
|
|
55
|
-
},
|
|
56
|
-
getTagLink: (tag) => {
|
|
57
|
-
return urlFormatter.addSlashToAddress(tagLink + tag.toLowerCase().replace(/ /g, '-') + '/1/');
|
|
58
|
-
}
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
/**
|
|
63
|
-
*
|
|
64
|
-
* @returns {Promise<Taxonomy>}
|
|
65
|
-
*/
|
|
66
|
-
export async function getTaxonomy () {
|
|
67
|
-
const cacheKey = 'Global__taxonomy';
|
|
68
|
-
|
|
69
|
-
/** @type {Taxonomy} */
|
|
70
|
-
let taxonomy = cache.getItem(cacheKey);
|
|
71
|
-
|
|
72
|
-
if (taxonomy == null) {
|
|
73
|
-
/** @type {MarkdownInstance[]} */
|
|
74
|
-
const allPages = posts.all().filter(PostFiltering.isListable);
|
|
75
|
-
|
|
76
|
-
/** @type {{ [key: string]: number }} */
|
|
77
|
-
const tags = {};
|
|
78
|
-
|
|
79
|
-
/** @type {{ [key: string]: number }} */
|
|
80
|
-
const cats = {};
|
|
81
|
-
|
|
82
|
-
// Get taxonomy and counts
|
|
83
|
-
allPages.forEach((p) => {
|
|
84
|
-
p.frontmatter.tags && (p.frontmatter.tags).forEach(t => {
|
|
85
|
-
tags[t] = (tags[t] ?? 0) + 1;
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
p.frontmatter.categories && (p.frontmatter.categories).forEach(c => {
|
|
89
|
-
cats[c] = (cats[c] ?? 0) + 1;
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
// Map into the taxonomy
|
|
94
|
-
taxonomy = {
|
|
95
|
-
tags: Object.keys(tags).sort().map(x => {
|
|
96
|
-
return {
|
|
97
|
-
title: x,
|
|
98
|
-
count: tags[x]
|
|
99
|
-
};
|
|
100
|
-
}),
|
|
101
|
-
topTags: [],
|
|
102
|
-
categories: Object.keys(cats).sort().map(x => {
|
|
103
|
-
return {
|
|
104
|
-
title: x,
|
|
105
|
-
count: cats[x]
|
|
106
|
-
};
|
|
107
|
-
})
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
// Get a list of "top tags" by usage count
|
|
111
|
-
const length = Math.min(taxonomy.categories.length, taxonomy.tags.length);
|
|
112
|
-
taxonomy.topTags = taxonomy.tags
|
|
113
|
-
.sort((a, b) => b.count - a.count)
|
|
114
|
-
.slice(0, length)
|
|
115
|
-
.sort((a, b) => {
|
|
116
|
-
if ( a.title < b.title ){
|
|
117
|
-
return -1;
|
|
118
|
-
}
|
|
119
|
-
if ( a.title > b.title ){
|
|
120
|
-
return 1;
|
|
121
|
-
}
|
|
122
|
-
return 0;
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
cache.setItem(cacheKey, taxonomy);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
return taxonomy;
|
|
129
|
-
}
|