mikser-io-layouts 2.1.0 → 2.4.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/index.js +15 -6
- package/lib/matching.js +24 -3
- package/package.json +2 -2
package/index.js
CHANGED
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
checksumsByCollection,
|
|
22
22
|
checksum as fileChecksum, checksumOf,
|
|
23
23
|
useDatabase,
|
|
24
|
+
writeOutput, reportUnchanged,
|
|
24
25
|
} from 'mikser-io'
|
|
25
26
|
|
|
26
27
|
import { createInspect } from './lib/inspect.js'
|
|
@@ -408,12 +409,20 @@ export function layouts(userOptions = {}) {
|
|
|
408
409
|
|
|
409
410
|
if (!skipWrite) {
|
|
410
411
|
const destinationFile = path.join(writeBase, entity.destination)
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
412
|
+
// writeOutput skips the write when the bytes already on
|
|
413
|
+
// disk are identical. Invalidation is deliberately
|
|
414
|
+
// conservative — an entity that merely READ another
|
|
415
|
+
// re-renders, because the engine cannot know which field
|
|
416
|
+
// was read — so byte-identical output is routine, and
|
|
417
|
+
// rewriting it moved mtime for live-reload, rsync and
|
|
418
|
+
// `find -newer` alike. mkdir/unlink moved inside it.
|
|
419
|
+
const wrote = await writeOutput(destinationFile, output.result)
|
|
420
|
+
if (wrote) {
|
|
421
|
+
logger.debug('Layout render finished: %s', entity.destination.replace(runtime.options.workingFolder, ''))
|
|
422
|
+
} else {
|
|
423
|
+
reportUnchanged(entity)
|
|
424
|
+
logger.debug('Layout render finished, output unchanged: %s', entity.destination.replace(runtime.options.workingFolder, ''))
|
|
425
|
+
}
|
|
417
426
|
} else {
|
|
418
427
|
logger.debug('Layout render finished (save:false, bytes only): %s', entity.id)
|
|
419
428
|
}
|
package/lib/matching.js
CHANGED
|
@@ -22,6 +22,7 @@ import path from 'node:path'
|
|
|
22
22
|
|
|
23
23
|
import _ from 'lodash'
|
|
24
24
|
import { primaryDestination } from './destination.js'
|
|
25
|
+
import { reportWarning } from 'mikser-io'
|
|
25
26
|
|
|
26
27
|
export function createOnProcessed({
|
|
27
28
|
runtime, useLogger, useJournal,
|
|
@@ -61,6 +62,10 @@ export function createOnProcessed({
|
|
|
61
62
|
// So 'post' does NOT match a document named 'post'; '@/post' and
|
|
62
63
|
// '/documents/post.md' both do.
|
|
63
64
|
const onName = pattern.startsWith('@/')
|
|
65
|
+
reportWarning('layout-pattern-no-match', {
|
|
66
|
+
pattern, layout: options.match[pattern], evaluated: matchTally.evaluated,
|
|
67
|
+
matchedAgainst: onName ? 'name' : 'id',
|
|
68
|
+
})
|
|
64
69
|
logger.warn(
|
|
65
70
|
'Layout pattern %j (→ %j) matched none of the %d entities evaluated. ' +
|
|
66
71
|
'It is matched against entity.%s%s. On an incremental run unchanged ' +
|
|
@@ -125,7 +130,13 @@ export function createOnProcessed({
|
|
|
125
130
|
for (const name of declared) {
|
|
126
131
|
const layout = await resolveLayout(name)
|
|
127
132
|
if (layout) {
|
|
128
|
-
|
|
133
|
+
// meta.layout / meta.layouts in the document's own
|
|
134
|
+
// frontmatter. Labelled so --explain says the choice
|
|
135
|
+
// came from the content, not from config — which is
|
|
136
|
+
// where you would otherwise go looking.
|
|
137
|
+
if (!resolved.find(l => l.name === layout.name)) {
|
|
138
|
+
resolved.push({ ...layout, matchedBy: 'meta.layout' })
|
|
139
|
+
}
|
|
129
140
|
} else {
|
|
130
141
|
logger.warn('Layout not found for %s: %s', entity.collection, entity.id, name)
|
|
131
142
|
}
|
|
@@ -142,7 +153,13 @@ export function createOnProcessed({
|
|
|
142
153
|
const name = options.match[pattern]
|
|
143
154
|
const layout = await resolveLayout(name)
|
|
144
155
|
if (layout && !matched.find(l => l.name === layout.name)) {
|
|
145
|
-
|
|
156
|
+
// Record WHICH pattern claimed it. With several
|
|
157
|
+
// patterns able to match one entity, "why did this
|
|
158
|
+
// page get that layout" is otherwise only answerable
|
|
159
|
+
// by re-running the matcher by hand — and it is the
|
|
160
|
+
// question asked whenever the answer is surprising.
|
|
161
|
+
// Surfaced by `mikser --explain`.
|
|
162
|
+
matched.push({ ...layout, matchedBy: pattern })
|
|
146
163
|
}
|
|
147
164
|
}
|
|
148
165
|
}
|
|
@@ -163,7 +180,11 @@ export function createOnProcessed({
|
|
|
163
180
|
const autoLayout = candidates.find(name => layouts[name])
|
|
164
181
|
if (autoLayout) {
|
|
165
182
|
const layout = await resolveLayout(autoLayout)
|
|
166
|
-
|
|
183
|
+
// Labelled so `mikser --explain` can distinguish "a
|
|
184
|
+
// pattern you wrote chose this" from "the name happened
|
|
185
|
+
// to match a layout file" — a distinction that decides
|
|
186
|
+
// whether the fix is in the config or in a filename.
|
|
187
|
+
if (layout) matched.push({ ...layout, matchedBy: 'auto-layout' })
|
|
167
188
|
logger.debug('Auto layout matched %s -> %s for %s', entity.name, autoLayout, entity.id)
|
|
168
189
|
} else {
|
|
169
190
|
logger.trace('Auto layout no match for %s tried: %s', entity.id, candidates.join(', '))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mikser-io-layouts",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
4
4
|
"description": "SSG-flavor task-production policy for mikser-io. Multi-match layout assignment, per-layout destinations, postprocess chain attachment, layout inspection.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
},
|
|
19
19
|
"homepage": "https://github.com/almero-digital-marketing/mikser-io-layouts#readme",
|
|
20
20
|
"peerDependencies": {
|
|
21
|
-
"mikser-io": "^9.
|
|
21
|
+
"mikser-io": "^9.18.0"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"globby": "^14.0.0",
|