domma-cms 1.8.43 → 1.8.44

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/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.8.44] - 2026-10-23
4
+
5
+ - **Blocks with empty fields no longer show raw HTML.** A block placeholder on its own line with nothing to fill it (`{{bio}}` when there is no bio) left a blank line, which ended the block's HTML in the Markdown, and what followed showed on the page as code - the About page's team card printed its contact links as raw tags. Such a line is now dropped when it fills empty (`fillTemplateLines()` in `markdown.js`), for collection displays and block short tags alike; a template's own blank lines stay, since they are how it hands a Markdown value to marked.
6
+ - **Inline code on an indented HTML line shows again.** `<code>` inside an HTML line indented four or more spaces came out as `SC1:0` - the code-region scrub stored the line holding the code's placeholder and restored it only once. Restore now restores what it brings back too.
7
+
3
8
  ## [1.8.43] - 2026-10-23
4
9
 
5
10
  - **What is inside a short tag is indented too.** Shift+Alt+F now indents the content of `[grid]`, `[col]`, `[card]`, `[tabs]` and the other container short tags by how deeply it nests, not only the tag lines, and Enter after an opening tag goes one deeper. A nested list or fenced code keeps its shape inside. The renderer takes the nesting indent off before anything else (a container's content loses the indent its lines share), so four spaces inside a card is no longer a code block - and a page written flat reads exactly as before (checked across the fleet's 1,700 pages).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "domma-cms",
3
- "version": "1.8.43",
3
+ "version": "1.8.44",
4
4
  "description": "File-based CMS powered by Domma and Fastify. Run npx domma-cms my-site to create a new project.",
5
5
  "type": "module",
6
6
  "main": "server/server.js",
@@ -423,10 +423,29 @@ export function buildBlockStyleTag(blockName, css) {
423
423
  * @param {object} e - Collection entry { id, data, meta }
424
424
  * @returns {string}
425
425
  */
426
+ /**
427
+ * A filled block goes into Markdown as HTML, and a blank line ends an HTML block:
428
+ * what follows, indented, marked then shows as code - raw tags on the page. A
429
+ * placeholder alone on its line with nothing to fill it (` {{bio}}` with no
430
+ * bio) made exactly that blank line, so such a line goes. The template's OWN
431
+ * blank lines stay: they are how a template hands a Markdown value to marked.
432
+ * Each line is filled by itself, in one pass as before.
433
+ */
434
+ function fillTemplateLines(template, fill) {
435
+ const PLACEHOLDER = /\{\{\{(\w+)\}\}\}|\{\{([\w_]+)(?::([^{}]+))?\}\}/g;
436
+ const out = [];
437
+ for (const line of template.split('\n')) {
438
+ const filled = line.replace(PLACEHOLDER, fill);
439
+ if (!filled.trim() && line.trim() && /\{\{/.test(line)) continue;
440
+ out.push(filled);
441
+ }
442
+ return out.join('\n');
443
+ }
444
+
426
445
  function interpolateBlockTemplate(blockTemplate, e) {
427
446
  // One pass: a raw value put in (pre-rendered HTML) is never read again for
428
447
  // placeholders - text that shows "{{title}}" keeps it.
429
- return blockTemplate.replace(/\{\{\{(\w+)\}\}\}|\{\{([\w_]+)(?::([^{}]+))?\}\}/g, (_, raw, key, fmt) => {
448
+ return fillTemplateLines(blockTemplate, (_, raw, key, fmt) => {
430
449
  // Entry values never carry a shortcode into the page (inertShortcodes);
431
450
  // the template's own markup is untouched.
432
451
  if (raw !== undefined) return inertShortcodes(String(e.data?.[raw] ?? ''));
@@ -510,7 +529,7 @@ function renderCollectionBlocks(entries, blockTemplate, emptyMsg, ctaOpts, cols,
510
529
  function renderBlockFromAttrs(tmpl, attrs, blockName = '') {
511
530
  // Triple-brace raw pass-through and `{{field}}` (optional `:format`, e.g. `{{date:DD MMM YYYY}}`)
512
531
  // in one pass, so a raw value is never read again for placeholders.
513
- const rendered = tmpl.replace(/\{\{\{(\w+)\}\}\}|\{\{([\w_]+)(?::([^{}]+))?\}\}/g, (_, rawKey, key, fmt) => {
532
+ const rendered = fillTemplateLines(tmpl, (_, rawKey, key, fmt) => {
514
533
  if (rawKey !== undefined) return String(attrs[rawKey] ?? '');
515
534
  const raw = attrs[key] ?? '';
516
535
  if (fmt) {
@@ -1967,7 +1986,10 @@ export function scrubCodeRegions(markdown, preserveIndented = false) {
1967
1986
  // Inline code spans (single or multiple backticks, non-greedy)
1968
1987
  scrubbed = scrubbed.replace(/`+[^`\n]+`+/g, placeholder);
1969
1988
 
1970
- const restore = (s) => s.replace(new RegExp(`\\x02SC${callId}:(\\d+)\\x03`, 'g'), (_, i) => store[parseInt(i, 10)]);
1989
+ // A stored region can hold an earlier placeholder of this same call - an indented
1990
+ // line (preserveIndented) holding an inline <code> - so what comes back is
1991
+ // restored too. Restoring it once left "SC1:0" on the page.
1992
+ const restore = (s) => s.replace(new RegExp(`\\x02SC${callId}:(\\d+)\\x03`, 'g'), (_, i) => restore(store[parseInt(i, 10)]));
1971
1993
  return {scrubbed, restore};
1972
1994
  }
1973
1995