Skip to content

JPROT
Docs Examples Showcase Publish GitHub
JPROTStart hereFirst siteWrite contentConfigureCustomizePublishCatalog elementsCLI referenceAPI referenceExamplesTroubleshootingFAQArchitectureComparisonShowcaseResumeBlogfrontmatter

On this page

How files become pagesFrontmatterCommon fieldsProjectsBlog postsDate orderingShortcodesSelf-closing formAttribute valuesRulesThe homepage fileSupported Markdown
JPROTStart hereFirst siteWrite contentConfigureCustomizePublishCatalog elementsCLI referenceAPI referenceExamplesTroubleshootingFAQArchitectureComparisonShowcaseResumeBlogfrontmatter

On this page

How files become pagesFrontmatterCommon fieldsProjectsBlog postsDate orderingShortcodesSelf-closing formAttribute valuesRulesThe homepage fileSupported Markdown
JPROT/Writing content

Writing content

Content is plain Markdown plus a YAML frontmatter block. This page documents the full content model. For a worked example, start with the Quick start.

How files become pages

Every Markdown file in content/ becomes a page at a URL matching its path:

FileURLPurpose
content/index.md/Homepage
content/about.md/aboutStandalone page
content/projects/x.md/projects/xProject — also a card on the homepage
content/blog.md/blogBlog listing page (layout: blog)
content/blog/x.md/blog/xBlog post, newest first

Sub-folders work: content/blog/2026/first-post.md → /blog/2026/first-post.

The file name becomes the URL path — a space stays a space (encoded as %20), so use lowercase letters and dashes for clean, readable URLs. JPROT converts dynamic content (like jprot new post "My Title") to dashed slugs.

Frontmatter

The block between two --- lines at the top of a file holds the page's settings. It is YAML: key: value lines.

The complete, precise syntax — which values, maps, lists and block scalars are accepted and which are not — is on the frontmatter reference page; what matters for pages is below.

---
title: About me
order: 1
nav: About
hidden: false
---

Common fields

FieldPurpose
titlePage title (browser tab + headings)
orderPosition in navigation / docs sidebar
navDifferent menu label (defaults to title)
hiddentrue hides the page from navigation (URL still works)
layoutForce a layout: home, blog, resume, or a custom component
draftWork in progress: hidden from production, search, feeds, exports
noindextrue → stays online but ignored by search engines
excerptOne-line summary for cards, feeds, search
imageTop-of-page image; also used for link previews and feeds
descriptionSEO description (falls back to excerpt)
heroPer-page hero block { title, subtitle, avatar, links }
sectionsPer-page portfolio sections (same shape as the homepage)

If a page is missing from the menu, add nav: (label) and order: (position).

Projects

A project is a Markdown file in content/projects/. Its frontmatter powers both the project card and the page:

---
title: Task Manager
order: 1
date: 2026-01-15
tags:
  - JavaScript
  - Node.js
excerpt: A command-line task manager.
cover: /img/task-manager.png
demo: https://example.com/demo
repo: https://github.com/you/task-manager
---
FieldShows up as
titleCard + page title
dateDate on the card
tagsFilter chips above the project grid
excerptCard description
demo / repoLive demo / Source buttons
coverCard image (a colored placeholder is drawn if absent)
imageOpen Graph / link-preview image
orderProject sort order

Blog posts

Posts live in content/blog/ (configurable via blogDir). The listing page is content/blog.md with layout: blog; every other file in the folder is a post, sorted newest first.

---
title: Hello, JPROT
date: 2026-01-05
tags:
  - jprot
excerpt: What landed in this release.
---

Post body here...

date, tags, and excerpt flow into the listing, RSS feed, and sitemap automatically. Create a draft instantly with jprot new post "Title" --draft.

Date ordering

Dates may be written as YYYY-MM-DD or YYYY-M-D. Both normalize to a zero-padded sort key, so 2026-1-5 sorts before 2026-10-1 correctly. An invalid date is flagged by jprot lint and omits <pubDate> from the feed.

Shortcodes

Any registered component can be placed inside a page with a :::Name block:

:::CTA title="Join now" text="Start today" label="Get started" url="/about"

Inner Markdown is rendered and passed to the component as children.

:::

:::Stats items='[{"value":15,"label":"Projects"}]'

Self-closing form

A component that takes no content can render on a single line — no closing fence needed:

:::AvatarHero avatar="/images/me.jpg" title="Mona Reyes"

Attribute values

ShapeExamplePassed as
stringtitle="Hello world""Hello world"
numberlevel=9090
booleandraft=truetrue
JSONitems='[{"name":"JS","level":90}]'real array/object

Rules

  • The block opens with :::Name (name = component filename) and closes with a lone ::: line.
  • A ::: line inside a fenced code block is literal — code fences are respected while scanning.
  • Shortcodes nest; inner content is re-rendered as Markdown.
  • Unknown names render a visible .jprot-shortcode-missing hint plus a terminal warning — a typo never 500s the page.

The homepage file

content/index.md uses the home layout. A hero block can live in its frontmatter instead of in jprot.config.js:

---
title: Home
layout: home
hero:
  title: Hello
  subtitle: A short tagline
---

Content below the frontmatter renders under the hero, above the project cards.

Supported Markdown

Headings, paragraphs (consecutive lines join into one paragraph), bold, italic (including nested emphasis like **bold _and_ nested**), inline code, fenced code blocks, ordered and unordered lists (nested lists included), GitHub-style task lists, blockquotes and callouts, tables, images, links, reference-style links, horizontal rules, and backslash escapes (* renders a literal star).

Extras on top of CommonMark:

  • Footnotes — reference with [^1], define anywhere with [^1]: text. A notes section with backlinks is appended automatically. Turn off with markdown.footnotes: false.
  • Autolinks — <https://example.com> and <you@example.com> become links automatically. Turn off with markdown.autolinks: false.
  • Task lists — - [ ] todo and - [x] done render as disabled checkboxes. Turn off with markdown.taskLists: false.
  • Reference links — write [text][id], [text][] or [text] and define the target once with [id]: https://example.com. Labels are case-insensitive; definitions may appear anywhere (even after use).

Every toggle lives under the markdown key in jprot.config.js.

Next: Configuration.

Previous← First site NextConfigure →

© 2026 JPROT — Built with JPROT