class

Hwaro::Models::Page

Inherits Reference / Object

Constants

MORE_MARKER_REGEX = /<!--\s*more\s*-->/i

Extract summary from content using <!-- more --> marker Returns content before the marker, or nil if no marker found Note: @raw_content has front matter already stripped during parsing

Fence-aware: a marker shown inside a fenced code block (a docs page demonstrating the feature) is literal text, not a split point. The per-line pattern no longer matches a marker whose parts sit on different lines — degenerate input the old multi-line \s* accepted.

Constructors

new(path : String)
Source

Instance methods

aliases
Source
aliases=(aliases : Array(String))
Source
ancestors

New: Ancestors - parent sections chain

Source
ancestors=(ancestors : Array(Page))

New: Ancestors - parent sections chain

Source
assets

New: Assets - static files in this page directory

Source
assets=(assets : Array(String))

New: Assets - static files in this page directory

Source
authors

New: Authors field (array of author names)

Source
authors=(authors : Array(String))

New: Authors field (array of author names)

Source
build_warnings

Build warnings collected during rendering (used for error overlay in serve mode)

Source
build_warnings=(build_warnings : Array(String))

Build warnings collected during rendering (used for error overlay in serve mode)

Source
calculate_reading_time(words_per_minute : Int32 = 200) : Int32

Calculate reading time in minutes (assuming ~200 words per minute)

Source
calculate_word_count

Calculate word count from raw content Note: @raw_content already has front matter stripped during parsing, so we only need to remove HTML tags and markdown syntax.

Source
cascade_fingerprint

Fingerprint of the merged section [cascade] values applied to this page (empty when none apply). Stored in the build cache so editing a parent _index.md's cascade invalidates descendant pages whose own source files did not change.

Source
cascade_fingerprint=(cascade_fingerprint : String)

Fingerprint of the merged section [cascade] values applied to this page (empty when none apply). Stored in the build cache so editing a parent _index.md's cascade invalidates descendant pages whose own source files did not change.

Source
collect_assets(content_dir : String, content_files : ContentFilesConfig | Nil = nil) : Array(String)

Collect assets from page directory

When content_files is configured ([content.files] with allow_extensions), co-located bundle assets are filtered through the SAME allow/disallow rules as standalone content files. Without this, a root _index.md turns the whole content/ tree into one recursive bundle and republishes arbitrary non-markdown files (e.g. content/public/robots.txt) to the output regardless of allow_extensions. When [content.files] is not configured, every non-markdown file is collected (unchanged behavior).

Source
content

Runtime / Computed Properties

Source
content=(content : String)

Runtime / Computed Properties

Source
custom_path
Source
custom_path=(custom_path : String | Nil)
Source
date
Source
date=(date : Time | Nil)
Source
description
Source
description=(description : String | Nil)
Source
draft
Source
draft=(draft : Bool)
Source
effective_summary

Get effective summary (summary or description fallback)

Source
excluded_from_listings?

True when a page should be omitted from generated listings (taxonomy indexes, related posts, …): drafts, preview-only unpublished pages, and synthetic generated pages.

Source
expires
Source
expires=(expires : Time | Nil)
Source
extra

New: Extra field for arbitrary custom metadata from front matter. Values are recursive (ExtraValue) so nested [extra.*] subtables and arrays-of-tables round-trip into {{ page.extra.a.b }} in templates.

Source
extra=(extra : Hash(String, ExtraValue))

New: Extra field for arbitrary custom metadata from front matter. Values are recursive (ExtraValue) so nested [extra.*] subtables and arrays-of-tables round-trip into {{ page.extra.a.b }} in templates.

Source
extract_summary
Source
front_matter_keys
Source
front_matter_keys=(front_matter_keys : Array(String))
Source
generated
Source
generated=(generated : Bool)
Source
has_redirect?

Check if page has redirect

Source
has_summary?

Check if page has summary (either from <!-- more --> or description)

Source
higher
Source
higher=(higher : Page | Nil)
Source
image
Source
image=(image : String | Nil)
Source
in_search_index

New: In search index - whether to include in search index

Source
in_search_index=(in_search_index : Bool)

New: In search index - whether to include in search index

Source
in_sitemap
Source
in_sitemap=(in_sitemap : Bool)
Source
is_index
Source
is_index=(is_index : Bool)
Source
language
Source
language=(language : String | Nil)
Source
lower

New: Lower/Higher page references (previous/next in section)

Source
lower=(lower : Page | Nil)

New: Lower/Higher page references (previous/next in section)

Source
parse_failed

Whether parsing (front-matter / markdown) failed for this page

Source
parse_failed=(parse_failed : Bool)

Whether parsing (front-matter / markdown) failed for this page

Source
path
Source
path=(path : String)
Source
plain_summary(limit : Int32 = 200) : String | Nil

Plain-text rendering of the &lt;!-- more --&gt; summary, safe to embed in single-line contexts like og:description, twitter:description, or a feed &lt;description&gt;. Uses the already-rendered summary_html and strips markup so raw markdown (## headings, code fences, math, literal newlines) never leaks into meta tags — see https://github.com/hahwul/hwaro/issues/491. Returns nil when the page has no summary. Soft-truncates to limit characters on a word boundary.

Source
raw_content
Source
raw_content=(raw_content : String)
Source
reading_time
Source
reading_time=(reading_time : Int32)
Source
redirect_to

New: Redirect to - URL to redirect this page to

Source
redirect_to=(redirect_to : String | Nil)

New: Redirect to - URL to redirect this page to

Source
refresh_unpublished!(now : Time)

Recompute unpublished from the publication window (date in the future or expires in the past) relative to the build's single now. Called by the parse-phase filter and the incremental (--cache) re-parse path so every downstream consumer sees a consistent value.

Source
render
Source
render=(render : Bool)
Source
search_index_eligible?

True when a page is eligible for the search index / llms.txt: it emits HTML, isn't a draft or preview-only unpublished page, opts into the search index, and isn't a synthetic generated listing page.

Source
section
Source
section=(section : String)
Source
series

New: Series support

Source
series=(series : String | Nil)

New: Series support

Source
series_index
Source
series_index=(series_index : Int32)
Source
series_pages
Source
series_pages=(series_pages : Array(Page))
Source
series_weight
Source
series_weight=(series_weight : Int32)
Source
slug
Source
slug=(slug : String | Nil)
Source
summary

New: Summary - content before <!-- more --> marker or auto-generated

Source
summary=(summary : String | Nil)

New: Summary - content before <!-- more --> marker or auto-generated

Source
summary_html

Rendered HTML for the chunk before &lt;!-- more --&gt;. Populated by the build pipeline after extract_summary runs and the markdown processor is available; nil for pages without a &lt;!-- more --&gt; marker (in which case page.summary falls back to description). See https://github.com/hahwul/hwaro/issues/491.

Source
summary_html=(summary_html : String | Nil)

Rendered HTML for the chunk before &lt;!-- more --&gt;. Populated by the build pipeline after extract_summary runs and the markdown processor is available; nil for pages without a &lt;!-- more --&gt; marker (in which case page.summary falls back to description). See https://github.com/hahwul/hwaro/issues/491.

Source
tags
Source
tags=(tags : Array(String))
Source
taxonomies
Source
taxonomies=(taxonomies : Hash(String, Array(String)))
Source
taxonomy_name
Source
taxonomy_name=(taxonomy_name : String | Nil)
Source
taxonomy_term
Source
taxonomy_term=(taxonomy_term : String | Nil)
Source
taxonomy_values(name : String) : Array(String)

Resolve the term list for a configured taxonomy name. Most taxonomies live in @taxonomies, but a few — tags and authors — are stored on dedicated Page properties so other features (the tags shortcut, the site.authors aggregation) can reach them without a hash lookup. Centralizing the fallback here keeps call sites (Taxonomies generator, related-posts scoring, …) from forgetting any of the special cases.

Source
template
Source
template=(template : String | Nil)
Source
title

Front Matter Properties

Source
title=(title : String)

Front Matter Properties

Source
toc=(toc : Bool)
Source
unpublished

True when the page is outside its publication window at build time (future date or past expires). Such pages only survive the parse filter under --include-future / --include-expired — preview flags — and must then behave exactly like drafts under --drafts: the HTML page renders, but the page stays out of every public discovery surface (sitemap, feeds, search index, llms.txt) and out of generated listings (taxonomies, series, related posts, authors).

Source
unpublished=(unpublished : Bool)

True when the page is outside its publication window at build time (future date or past expires). Such pages only survive the parse filter under --include-future / --include-expired — preview flags — and must then behave exactly like drafts under --drafts: the HTML page renders, but the page stays out of every public discovery surface (sitemap, feeds, search index, llms.txt) and out of generated listings (taxonomies, series, related posts, authors).

Source
updated
Source
updated=(updated : Time | Nil)
Source
url=(url : String)
Source
weight
Source
weight=(weight : Int32)
Source
word_count

New: Word count and reading time (computed)

Source
word_count=(word_count : Int32)

New: Word count and reading time (computed)

Source