Coming soon (likely this afternoon, I’m writing tests and docs and updating examples as we speak)…

This is the sort of thing you’ll be able to do with Markdown pages. Just pop any arbitrary JavaScript you want in the new script block in the front matter and then import and use components as well as plain old JavaScript tagged template variable interpolation (not shown in this example) inside your Markdown.

The screen has all the code (sans the end of the last line of CSS and the closing tags for the

Screenshot: three windows: left side: Source of index.page.md, top-right browser showing running web app, bottom-right, source of Button and Reactions components.

Contents of windows:

index.page.md:

---
title: An interactive markdown page
script: |
  import Reaction from './Reaction.fragment.js'

  // Initialise database if necessary.
  kitten.db.reactions ??= {}
  kitten.db.reactions.Heart ??= 0
  kitten.db.reactions.Confetti ??= 0
  kitten.db.reactions.Smiley ??= 0

  let page

  export function onConnect (data) {
    page = data.page
  }

  export function onReaction (data) {
    kitten.db.reactions[data.type]++
    page.send(kitten.html`<${Reaction} />`)
  }
---
<page css>

# Hello!

While this is a __markdown__ page, I can easily layer interactivity by adding a simple component in a script block.

## Reactions{id=your-reactions}

<${Reaction} />

Browser (output):

Hello!
While this is a markdown page, I can easily layer interactivity by adding a simple component in a script block.

Reactions

Heart button: 5
Confetti button: 4
Smiley button: 3
Screenshot: three windows: left side: Source of index.page.md, top-right browser showing running web app, bottom-right, source of Button and Reactions components. Contents of windows: index.page.md: --- title: An interactive markdown page script: | import Reaction from './Reaction.fragment.js' // Initialise database if necessary. kitten.db.reactions ??= {} kitten.db.reactions.Heart ??= 0 kitten.db.reactions.Confetti ??= 0 kitten.db.reactions.Smiley ??= 0 let page export function onConnect (data) { page = data.page } export function onReaction (data) { kitten.db.reactions[data.type]++ page.send(kitten.html`<${Reaction} />`) } --- <page css> # Hello! While this is a __markdown__ page, I can easily layer interactivity by adding a simple component in a script block. ## Reactions{id=your-reactions} <${Reaction} /> Browser (output): Hello! While this is a markdown page, I can easily layer interactivity by adding a simple component in a script block. Reactions Heart button: 5 Confetti button: 4 Smiley button: 3

Not coming this afternoon :)

Just realised that I’m not handling nested interpolated values properly as I’m using a regular expression to simulate what JavaScript’s native tagged template feature does.

Instead, I have to write a simple parser.

If I had a penny for every time I started with regular expressions on this and then had to implement a proper parser afterwards… I’d have two pennies (the other time was for extracted nested tags. See a pattern? (I’m here all week.)

So, barring the discovery of other edge (or not-so edge) cases following further testing, I’m going to aim for middle of the week for the release of the new Markdown Pages feature.

kitten💕

#Kitten#KittenUpdate #SmallWeb

@aral And we all know that regex usage leaves you with two problems - https://regex.info/blog/2006-09-15/247

(disclaimer: Perl is still my true love, even though I've no avenue to use it at work save for some old library systems' bespoke scripts that need a tweak whenever we upgrade Dead Rat Linux majors. And I really like regexes when appropriate, which for text processing is very often)

OK, so here’s likely the simplest possible example demonstrating:

• The same route, implemented as both a Kitten JavaScript Page (.page.js) and as a Kitten Markdown Page (.page.md)

• How to persist to the default Kitten JSDB¹ database.

(That first line with the nullish coalescing operator creates a “table” on the database with a default value for the count if it doesn’t already exist.)

kitten.small-web.org

¹ kitten.small-web.org/tutorials

Alt text (continued due to Mastodon’s 1500 character limit on alt-text):

Source of Button and Reactions components:

/**
Simple Reactions control.

Broadcasts «reaction» event.
*/
function Button ({ Icon }) {
const iconName = Icon.name
return kitten.html<br/> &lt;div class=&#39;reaction&#39;&gt;<br/> &lt;button name=&#39;reaction&#39; data=&#39;type:&quot;${iconName}&quot;&#39; connect&gt;<br/> &lt;${Icon} weight=duotone alt=${Icon.name} colour=deeppink&gt;&lt;title&gt;${Icon.name}&lt;/title&gt;&lt;/&gt;<br/> &lt;/button&gt;<br/> ${kitten.db.reactions[iconName]}<br/> &lt;/div&gt;<br/>
}

export default function Reactions () {
return kitten.html<br/> &lt;div id=&#39;reactions&#39; morph&gt;<br/> &lt;${Button} Icon=${kitten.icons.Heart} /&gt;<br/> &lt;${Button} Icon=${kitten.icons.Confetti} /&gt;<br/> &lt;${Button} Icon=${kitten.icons.Smiley} /&gt;<br/> &lt;style&gt;<br/> button { background: var(--background-alt); }<br/> button:hover { background: var(--background); }<br/><a href="/hashtag/01K2YA2TYMB4Q0WKY3PP9QD1KY">#<span>reactions</span></a> { display: flex; }<br/> .reaction { display: flex; flex-direction: column; align-items: center; font-size: 2em;}<br/> &lt;/style&gt;<br/> &lt;/div&gt;<br/>
}