coralite-plugin-aggregation 0.8.0 → 0.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/LICENSE +328 -661
- package/lib/components/coralite-pagination.html +99 -0
- package/lib/index.js +196 -239
- package/package.json +3 -6
- package/types/index.js +2 -2
- package/lib/templates/coralite-pagination.html +0 -123
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
<template id="coralite-pagination">
|
|
2
|
+
<nav aria-label="{{ ariaLabel }}">
|
|
3
|
+
<ul class="pagination">
|
|
4
|
+
{{ paginationLinks }}
|
|
5
|
+
</ul>
|
|
6
|
+
</nav>
|
|
7
|
+
</template>
|
|
8
|
+
|
|
9
|
+
<script type="module">
|
|
10
|
+
import { defineComponent } from 'coralite/plugins'
|
|
11
|
+
|
|
12
|
+
export default defineComponent({
|
|
13
|
+
attributes: {
|
|
14
|
+
ariaLabel: { type: String, default: 'Page navigation' },
|
|
15
|
+
currentPage: { type: Number, default: 1 },
|
|
16
|
+
totalPages: { type: Number, default: 1 },
|
|
17
|
+
maxVisible: { type: Number, default: 5 },
|
|
18
|
+
baseUrl: { type: String, default: '' },
|
|
19
|
+
urlPrefix: { type: String, default: '' },
|
|
20
|
+
segment: { type: String, default: 'page' },
|
|
21
|
+
ellipsis: { type: String, default: '...' }
|
|
22
|
+
},
|
|
23
|
+
getters: {
|
|
24
|
+
paginationLinks: (state) => {
|
|
25
|
+
const getPageUrl = (page) => {
|
|
26
|
+
if (page === 1) {
|
|
27
|
+
return state.baseUrl;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const cleanPrefix = state.urlPrefix.endsWith('/') ? state.urlPrefix : `${state.urlPrefix}/`;
|
|
31
|
+
return `${cleanPrefix}${state.segment}/${page}.html`;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const createItem = (page, text, isActive, isDisabled) => {
|
|
35
|
+
let className = 'page-item';
|
|
36
|
+
if (isActive) className += ' active';
|
|
37
|
+
if (isDisabled) className += ' disabled';
|
|
38
|
+
|
|
39
|
+
let attr = '';
|
|
40
|
+
if (isActive) attr += ' aria-current="page"';
|
|
41
|
+
if (isDisabled) attr += ' tabindex="-1" aria-disabled="true"';
|
|
42
|
+
|
|
43
|
+
const href = isDisabled ? '#' : getPageUrl(page);
|
|
44
|
+
|
|
45
|
+
return `<li class="${className}"><a class="page-link" href="${href}"${attr}>${text}</a></li>`;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let links = '';
|
|
49
|
+
|
|
50
|
+
// Previous Link
|
|
51
|
+
links += createItem(state.currentPage - 1, 'Previous', false, state.currentPage <= 1);
|
|
52
|
+
|
|
53
|
+
// Calculate Window (Start/End)
|
|
54
|
+
const half = Math.floor(state.maxVisible / 2);
|
|
55
|
+
let start = state.currentPage - half;
|
|
56
|
+
let end = state.currentPage + half;
|
|
57
|
+
|
|
58
|
+
if (start < 1) {
|
|
59
|
+
start = 1;
|
|
60
|
+
end = Math.min(state.totalPages, state.maxVisible);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (end > state.totalPages) {
|
|
64
|
+
end = state.totalPages;
|
|
65
|
+
start = Math.max(1, state.totalPages - state.maxVisible + 1);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const showFirst = start > 1;
|
|
69
|
+
const showLast = end < state.totalPages;
|
|
70
|
+
|
|
71
|
+
// First page + ellipsis
|
|
72
|
+
if (showFirst) {
|
|
73
|
+
links += createItem(1, '1', false, false);
|
|
74
|
+
if (start > 2) {
|
|
75
|
+
links += `<li class="page-item disabled"><span class="page-link">${state.ellipsis}</span></li>`;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Main window loop
|
|
80
|
+
for (let i = start; i <= end; i++) {
|
|
81
|
+
links += createItem(i, i, i === state.currentPage, false);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Last page + ellipsis
|
|
85
|
+
if (showLast) {
|
|
86
|
+
if (end < state.totalPages - 1) {
|
|
87
|
+
links += `<li class="page-item disabled"><span class="page-link">${state.ellipsis}</span></li>`;
|
|
88
|
+
}
|
|
89
|
+
links += createItem(state.totalPages, state.totalPages, false, false);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Next Link
|
|
93
|
+
links += createItem(state.currentPage + 1, 'Next', false, state.currentPage >= state.totalPages);
|
|
94
|
+
|
|
95
|
+
return links;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
})
|
|
99
|
+
</script>
|
package/lib/index.js
CHANGED
|
@@ -1,286 +1,243 @@
|
|
|
1
1
|
import { definePlugin } from 'coralite'
|
|
2
2
|
import path from 'node:path'
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
4
|
+
export const aggregation = definePlugin({
|
|
5
|
+
name: 'aggregation',
|
|
6
|
+
|
|
7
|
+
async exports(options) {
|
|
8
|
+
const {
|
|
9
|
+
path: paths = [],
|
|
10
|
+
component,
|
|
11
|
+
pagination,
|
|
12
|
+
filter,
|
|
13
|
+
sort,
|
|
14
|
+
limit,
|
|
15
|
+
offset = 0,
|
|
16
|
+
recursive = false,
|
|
17
|
+
transformState
|
|
18
|
+
} = options
|
|
19
|
+
const state = this.state || {}
|
|
20
|
+
const app = this.app
|
|
21
|
+
const pagesRoot = app.options.pages
|
|
22
|
+
|
|
23
|
+
// Collect pages
|
|
24
|
+
let allPages = []
|
|
25
|
+
const uniquePaths = new Set()
|
|
26
|
+
|
|
27
|
+
for (const relativePath of paths) {
|
|
28
|
+
const targetPath = path.join(pagesRoot, relativePath)
|
|
29
|
+
|
|
30
|
+
if (!recursive) {
|
|
31
|
+
const pagesInDir = app.pages.getListByPath(targetPath)
|
|
32
|
+
|
|
33
|
+
if (pagesInDir) {
|
|
34
|
+
for (const page of pagesInDir) {
|
|
35
|
+
const pagePath = page.path.pathname
|
|
36
|
+
|
|
37
|
+
if (!uniquePaths.has(pagePath)) {
|
|
38
|
+
uniquePaths.add(pagePath)
|
|
39
|
+
allPages.push(page)
|
|
40
|
+
}
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
uniquePaths.
|
|
52
|
-
|
|
43
|
+
} else {
|
|
44
|
+
// Recursive search
|
|
45
|
+
for (const page of app.pages.list) {
|
|
46
|
+
const dirname = page.path.dirname
|
|
47
|
+
|
|
48
|
+
if (dirname === targetPath || dirname.startsWith(targetPath + path.sep)) {
|
|
49
|
+
const pagePath = page.path.pathname
|
|
50
|
+
|
|
51
|
+
if (!uniquePaths.has(pagePath)) {
|
|
52
|
+
uniquePaths.add(pagePath)
|
|
53
|
+
allPages.push(page)
|
|
54
|
+
}
|
|
53
55
|
}
|
|
54
56
|
}
|
|
55
57
|
}
|
|
56
58
|
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Filter
|
|
60
|
-
if (typeof filter === 'function') {
|
|
61
|
-
allPages = allPages.filter(page => {
|
|
62
|
-
// Access values from result property
|
|
63
|
-
const values = page.result && page.result.values ? page.result.values : page.values
|
|
64
|
-
return filter(values)
|
|
65
|
-
})
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
// Sort
|
|
69
|
-
if (typeof sort === 'function') {
|
|
70
|
-
allPages.sort((a, b) => {
|
|
71
|
-
const valA = a.result && a.result.values ? a.result.values : a.values
|
|
72
|
-
const valB = b.result && b.result.values ? b.result.values : b.values
|
|
73
|
-
return sort(valA, valB)
|
|
74
|
-
})
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Pagination
|
|
78
|
-
let startIndex = offset
|
|
79
|
-
let endIndex = allPages.length
|
|
80
|
-
|
|
81
|
-
let currentPage = 1
|
|
82
|
-
let totalPages = 1
|
|
83
|
-
|
|
84
|
-
// Ensure renderContext is available
|
|
85
|
-
const currentRenderContext = contextInstance.renderContext
|
|
86
|
-
const buildId = currentRenderContext && currentRenderContext.buildId
|
|
87
|
-
|
|
88
|
-
if (limit) {
|
|
89
|
-
if (pagination) {
|
|
90
|
-
const segment = pagination.segment || 'page'
|
|
91
|
-
const urlPathname = contextValues.page_url_pathname || ''
|
|
92
59
|
|
|
93
|
-
|
|
60
|
+
// Filter
|
|
61
|
+
if (typeof filter === 'function') {
|
|
62
|
+
allPages = allPages.filter(page => {
|
|
63
|
+
return filter(page.result.state)
|
|
64
|
+
})
|
|
65
|
+
}
|
|
94
66
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
67
|
+
// Sort
|
|
68
|
+
if (typeof sort === 'function') {
|
|
69
|
+
allPages.sort((a, b) => {
|
|
70
|
+
const propsA = (a.result && a.result.state) ? a.result.state : a.state
|
|
71
|
+
const propsB = (b.result && b.result.state) ? b.result.state : b.state
|
|
72
|
+
return sort(propsA, propsB)
|
|
73
|
+
})
|
|
74
|
+
}
|
|
98
75
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
76
|
+
// Pagination
|
|
77
|
+
let startIndex = offset
|
|
78
|
+
let endIndex = allPages.length
|
|
102
79
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
if (
|
|
111
|
-
const
|
|
112
|
-
const
|
|
113
|
-
const currentFilename = currentDocument.path.filename
|
|
114
|
-
const currentDirname = currentDocument.path.dirname
|
|
115
|
-
|
|
116
|
-
// Determine the output path structure based on rules
|
|
117
|
-
let targetDir = currentDirname
|
|
118
|
-
let urlPrefixBase = ''
|
|
119
|
-
|
|
120
|
-
// Rules:
|
|
121
|
-
// /index.html -> /page/1.html (relative to currentDirname)
|
|
122
|
-
// /blog.html -> /blog/page/1.html (creates subdirectory)
|
|
123
|
-
// /blog/index.html -> /blog/page/1.html (relative to currentDirname)
|
|
124
|
-
// /blog/today.html -> /blog/today/page/1.html (creates subdirectory)
|
|
125
|
-
|
|
126
|
-
if (currentFilename === 'index.html') {
|
|
127
|
-
// Standard case: keep in same directory
|
|
128
|
-
targetDir = currentDirname
|
|
129
|
-
// Prefix for URL generation in child
|
|
130
|
-
urlPrefixBase = path.dirname(urlPathname) // e.g. /blog/
|
|
131
|
-
} else {
|
|
132
|
-
// Named file: create subdirectory with same name (minus extension)
|
|
133
|
-
const basename = path.basename(currentFilename, path.extname(currentFilename))
|
|
134
|
-
targetDir = path.join(currentDirname, basename)
|
|
80
|
+
let currentPage = 1
|
|
81
|
+
let totalPages = 1
|
|
82
|
+
|
|
83
|
+
const currentRenderContext = this.renderContext
|
|
84
|
+
const buildId = currentRenderContext && currentRenderContext.buildId
|
|
85
|
+
|
|
86
|
+
if (limit) {
|
|
87
|
+
if (pagination) {
|
|
88
|
+
const segment = pagination.segment || 'page'
|
|
89
|
+
const urlPathname = this.page.url.pathname
|
|
135
90
|
|
|
136
|
-
|
|
137
|
-
|
|
91
|
+
const escapedSegment = segment.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
92
|
+
const segmentRegex = new RegExp(`/${escapedSegment}/(\\d+)`)
|
|
93
|
+
const match = urlPathname.match(segmentRegex)
|
|
94
|
+
|
|
95
|
+
if (match) {
|
|
96
|
+
currentPage = parseInt(match[1], 10)
|
|
138
97
|
}
|
|
139
98
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
99
|
+
startIndex = offset + (currentPage - 1) * limit
|
|
100
|
+
endIndex = startIndex + limit
|
|
101
|
+
totalPages = Math.ceil(allPages.length / limit)
|
|
102
|
+
|
|
103
|
+
if (!match && currentPage === 1 && totalPages > 1 && buildId) {
|
|
104
|
+
const currentPathname = this.page.file.pathname
|
|
105
|
+
const currentFilename = this.page.file.filename
|
|
106
|
+
const currentDirname = this.page.file.dirname
|
|
107
|
+
|
|
108
|
+
let targetDir = currentDirname
|
|
109
|
+
let urlPrefixBase = ''
|
|
110
|
+
|
|
111
|
+
if (currentFilename === 'index.html') {
|
|
112
|
+
targetDir = currentDirname
|
|
113
|
+
urlPrefixBase = path.dirname(urlPathname)
|
|
114
|
+
} else {
|
|
115
|
+
const basename = path.basename(currentFilename, path.extname(currentFilename))
|
|
116
|
+
targetDir = path.join(currentDirname, basename)
|
|
117
|
+
urlPrefixBase = urlPathname.replace(path.extname(currentFilename), '')
|
|
118
|
+
}
|
|
144
119
|
|
|
145
|
-
if (currentFilename === 'index.html') {
|
|
146
|
-
// If /index.html, urlPathname /index.html. dirname /. prefix /.
|
|
147
|
-
// If /blog/index.html, urlPathname /blog/index.html. dirname /blog. prefix /blog/.
|
|
148
|
-
urlPrefixBase = path.dirname(urlPathname)
|
|
149
120
|
if (!urlPrefixBase.endsWith('/')) urlPrefixBase += '/'
|
|
150
|
-
}
|
|
151
121
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
for (let i = 2; i <= totalPages; i++) {
|
|
156
|
-
const newPathname = path.join(targetDir, segment, `${i}.html`)
|
|
157
|
-
|
|
158
|
-
const virtualItem = {
|
|
159
|
-
content: currentItem ? currentItem.content : '', // Use original content
|
|
160
|
-
path: {
|
|
161
|
-
pathname: newPathname,
|
|
162
|
-
dirname: path.dirname(newPathname),
|
|
163
|
-
filename: path.basename(newPathname)
|
|
164
|
-
},
|
|
165
|
-
values: {
|
|
166
|
-
// Pass metadata to help resolve paths in children
|
|
167
|
-
meta_pagination_base_url: urlPathname,
|
|
168
|
-
// Calculate prefix once and pass it down
|
|
169
|
-
meta_pagination_url_prefix: urlPrefixBase
|
|
170
|
-
},
|
|
171
|
-
type: 'page'
|
|
122
|
+
if (currentFilename === 'index.html') {
|
|
123
|
+
urlPrefixBase = path.dirname(urlPathname)
|
|
124
|
+
if (!urlPrefixBase.endsWith('/')) urlPrefixBase += '/'
|
|
172
125
|
}
|
|
173
126
|
|
|
174
|
-
|
|
175
|
-
|
|
127
|
+
const currentItem = app.pages.getItem(currentPathname)
|
|
128
|
+
|
|
129
|
+
for (let i = 2; i <= totalPages; i++) {
|
|
130
|
+
const newPathname = path.join(targetDir, segment, `${i}.html`)
|
|
131
|
+
|
|
132
|
+
const virtualItem = {
|
|
133
|
+
content: currentItem ? currentItem.content : '',
|
|
134
|
+
path: {
|
|
135
|
+
pathname: newPathname,
|
|
136
|
+
dirname: path.dirname(newPathname),
|
|
137
|
+
filename: path.basename(newPathname)
|
|
138
|
+
},
|
|
139
|
+
state: {
|
|
140
|
+
paginationBaseUrl: urlPathname,
|
|
141
|
+
paginationUrlPrefix: urlPrefixBase
|
|
142
|
+
},
|
|
143
|
+
type: 'page'
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
await app.addRenderQueue(virtualItem, buildId)
|
|
147
|
+
}
|
|
176
148
|
}
|
|
149
|
+
} else {
|
|
150
|
+
endIndex = Math.min(startIndex + limit, allPages.length)
|
|
177
151
|
}
|
|
178
|
-
} else {
|
|
179
|
-
// Simple limit/offset without pagination logic
|
|
180
|
-
endIndex = Math.min(startIndex + limit, allPages.length)
|
|
181
152
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
153
|
+
|
|
154
|
+
const paginatedPages = allPages.slice(startIndex, endIndex)
|
|
155
|
+
const resultNodes = []
|
|
156
|
+
|
|
157
|
+
for (const page of paginatedPages) {
|
|
158
|
+
const pageProps = (page.result && page.result.state) ? page.result.state : page.state
|
|
159
|
+
let itemProps = { ...pageProps }
|
|
160
|
+
|
|
161
|
+
// Apply properties transformations
|
|
162
|
+
if (transformState && typeof transformState === 'object') {
|
|
163
|
+
for (const key in transformState) {
|
|
164
|
+
if (Object.prototype.hasOwnProperty.call(transformState, key)) {
|
|
165
|
+
const transform = transformState[key]
|
|
166
|
+
if (typeof transform === 'string') {
|
|
167
|
+
itemProps[key] = pageProps[transform]
|
|
168
|
+
} else if (typeof transform === 'function') {
|
|
169
|
+
itemProps[key] = transform(pageProps)
|
|
170
|
+
}
|
|
200
171
|
}
|
|
201
172
|
}
|
|
202
173
|
}
|
|
203
|
-
}
|
|
204
174
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
})
|
|
175
|
+
if (component) {
|
|
176
|
+
const componentElement = await app.createComponentElement({
|
|
177
|
+
id: component,
|
|
178
|
+
state: itemProps,
|
|
179
|
+
page: this.page,
|
|
180
|
+
renderContext: currentRenderContext
|
|
181
|
+
})
|
|
213
182
|
|
|
214
|
-
|
|
215
|
-
|
|
183
|
+
if (componentElement && componentElement.children) {
|
|
184
|
+
resultNodes.push(...componentElement.children)
|
|
185
|
+
}
|
|
216
186
|
}
|
|
217
187
|
}
|
|
218
|
-
}
|
|
219
188
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
const escapedSegment = segment.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
|
224
|
-
|
|
225
|
-
const paginationTemplateId = pagination.template || 'coralite-pagination'
|
|
189
|
+
if (pagination) {
|
|
190
|
+
const paginationComponentId = pagination.component || 'coralite-pagination'
|
|
191
|
+
const urlPathname = this.page.url.pathname
|
|
226
192
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
let baseUrl = urlPathname
|
|
230
|
-
let urlPrefix = ''
|
|
193
|
+
let baseUrl = urlPathname
|
|
194
|
+
let urlPrefix = ''
|
|
231
195
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
196
|
+
if (state.paginationBaseUrl) {
|
|
197
|
+
baseUrl = state.paginationBaseUrl
|
|
198
|
+
}
|
|
235
199
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
} else {
|
|
239
|
-
// Page 1 logic calculation if not passed
|
|
240
|
-
if (baseUrl.endsWith('/index.html') || baseUrl.endsWith('/')) {
|
|
241
|
-
urlPrefix = path.dirname(baseUrl)
|
|
200
|
+
if (state.paginationUrlPrefix) {
|
|
201
|
+
urlPrefix = state.paginationUrlPrefix
|
|
242
202
|
} else {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
203
|
+
if (baseUrl.endsWith('/index.html') || baseUrl.endsWith('/')) {
|
|
204
|
+
urlPrefix = path.dirname(baseUrl)
|
|
205
|
+
} else {
|
|
206
|
+
const basename = path.basename(baseUrl, '.html')
|
|
207
|
+
urlPrefix = path.join(path.dirname(baseUrl), basename)
|
|
208
|
+
}
|
|
246
209
|
}
|
|
247
|
-
}
|
|
248
210
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
}
|
|
211
|
+
if (!urlPrefix.endsWith('/')) urlPrefix += '/'
|
|
212
|
+
|
|
213
|
+
const paginationProps = {
|
|
214
|
+
'current-page': String(currentPage),
|
|
215
|
+
'total-pages': String(totalPages),
|
|
216
|
+
'base-url': baseUrl,
|
|
217
|
+
'url-prefix': urlPrefix,
|
|
218
|
+
segment: pagination.segment || 'page',
|
|
219
|
+
'max-visible': String(pagination.maxVisible || 5),
|
|
220
|
+
'aria-label': pagination.ariaLabel || 'Pagination',
|
|
221
|
+
ellipsis: pagination.ellipsis || '...'
|
|
222
|
+
}
|
|
262
223
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
224
|
+
const componentElement = await app.createComponentElement({
|
|
225
|
+
id: paginationComponentId,
|
|
226
|
+
state: paginationProps,
|
|
227
|
+
page: this.page,
|
|
228
|
+
renderContext: currentRenderContext
|
|
229
|
+
})
|
|
269
230
|
|
|
270
|
-
|
|
271
|
-
|
|
231
|
+
if (componentElement && componentElement.children) {
|
|
232
|
+
resultNodes.push(...componentElement.children)
|
|
233
|
+
}
|
|
272
234
|
}
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
return resultNodes
|
|
276
|
-
}
|
|
277
235
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
method: aggregationMethod,
|
|
236
|
+
return resultNodes
|
|
237
|
+
},
|
|
281
238
|
components: [
|
|
282
239
|
// @ts-ignore
|
|
283
|
-
path.join(import.meta.dirname, '
|
|
240
|
+
path.join(import.meta.dirname, 'components/coralite-pagination.html')
|
|
284
241
|
]
|
|
285
242
|
})
|
|
286
243
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "coralite-plugin-aggregation",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "A Coralite plugin for dynamically collecting, filtering, sorting, and displaying content across multiple sources. Build database-free Coralite websites with automated content aggregation.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -39,14 +39,11 @@
|
|
|
39
39
|
"lib",
|
|
40
40
|
"types"
|
|
41
41
|
],
|
|
42
|
-
"
|
|
43
|
-
"coralite": "^0.32.0"
|
|
44
|
-
},
|
|
45
|
-
"license": "AGPL-3.0-only",
|
|
42
|
+
"license": "MPL-2.0",
|
|
46
43
|
"devDependencies": {
|
|
47
44
|
"@stylistic/eslint-plugin-js": "^4.2.0",
|
|
48
45
|
"@stylistic/eslint-plugin-plus": "^4.2.0",
|
|
49
|
-
"coralite": "^0.
|
|
46
|
+
"coralite": "^0.34.0"
|
|
50
47
|
},
|
|
51
48
|
"scripts": {
|
|
52
49
|
"test": "node --test ./tests/index.spec.js"
|
package/types/index.js
CHANGED
|
@@ -10,14 +10,14 @@
|
|
|
10
10
|
/**
|
|
11
11
|
* @typedef {Object} AggregationOptions
|
|
12
12
|
* @property {string[]} [path=[]] - An array of relative paths to search for pages within `pagesRoot`.
|
|
13
|
-
* @property {string} [
|
|
13
|
+
* @property {string} [component] - The component ID to use for rendering each item found.
|
|
14
14
|
* @property {AggregationPaginationOptions} [pagination] - Configuration for pagination logic and controls. If present, pagination logic is enabled.
|
|
15
15
|
* @property {function(Object): boolean} [filter] - A callback function to filter pages. It receives the page values object and should return `true` to keep the item.
|
|
16
16
|
* @property {function(Object, Object): number} [sort] - A comparison function for sorting pages. It receives two page value objects (a, b) and should return a number.
|
|
17
17
|
* @property {number} [limit] - The maximum number of items to return (or items per page if pagination is used).
|
|
18
18
|
* @property {number} [offset=0] - The starting index for fetching items.
|
|
19
19
|
* @property {boolean} [recursive=false] - If true, searches subdirectories of the specified paths.
|
|
20
|
-
* @property {Object.<string, (string|function(Object): *)>} [
|
|
20
|
+
* @property {Object.<string, (string|function(Object): *)>} [transformState] - A map of key transformations. Keys are the new property names. Values can be a string (source property name) or a function (receiving page values and returning the new value).
|
|
21
21
|
*/
|
|
22
22
|
|
|
23
23
|
export default {}
|