class

Hwaro::Services::Creator

Inherits Reference / Object

Constants

ARCHETYPES_DIR = "archetypes"
CONTENT_DIR = "content"
HWARO_DIRECTIVE_RE = /\A<!--\s*hwaro:\s*(.*?)\s*-->\s*\n?/

&lt;!-- hwaro: KEY[=VALUE], KEY[=VALUE] --&gt; directive that an archetype can put on its very first line to declare metadata hwaro should honour (and strip) before applying the template. Keeping it an HTML comment means the archetype still parses cleanly if hwaro isn't the one reading it.

KNOWN_DIRECTIVES = {"bundle"}

Keys accepted inside &lt;!-- hwaro: ... --&gt;. Anything else is logged as a warning so typos (bundlr=true) surface instead of silently becoming no-ops.

PATH_SEP = '/'

Path separator used by hwaro-managed content paths. Hwaro stores and emits POSIX-style paths internally (the normalizer canonicalizes to this), so URL-safety checks compare against '/' rather than File::SEPARATOR to stay consistent on Windows hosts too.

TOML_DATETIME_RE = /\A\d{4}-\d{2}-\d{2}(?:[T ]\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})?)?\z/

TOML datetime literal pattern (local-date / local-datetime / offset-datetime per the spec). When the value matches, emit unquoted so the parser returns a real Time; otherwise fall back to a quoted string so unusual --date inputs still produce valid TOML.

Class methods

parseable_content_date?(value : String) : Bool

True when the build's front-matter date parser can produce a real Time from value. This mirrors Processors::Markdown#parse_time (format selection included — keep the two in sync) so hwaro new fails fast on a --date the build would silently drop (2026-13-45, not-a-date) or, worse, emit as an unquoted-but-invalid TOML datetime that breaks parsing of the whole generated file.

Source
sanitize_url_path(path : String) : String

Rewrite a path so every segment is URL-safe (see url_safe_path?). Unsafe characters (spaces, !@#$%^&amp;*(), etc.) are collapsed to a single -; leading/trailing hyphens per segment are trimmed. Segments that reduce to the empty string after sanitization are dropped so the result never grows spurious // or leading-slash artifacts.

Preserves original casing — filesystems differ on case sensitivity, and silently lowercasing could clobber existing content. Authors who want an all-lowercase slug can pass one explicitly.

Raises ArgumentError when every segment sanitizes away — the caller (the CLI) wraps that into a classified usage error.

Source
slugify(title : String) : String

Derive a filename-safe slug from a free-text title: lowercase, then collapse every run of non-letter/non-digit Unicode characters to a single hyphen and trim hyphens off the ends. Returns &quot;&quot; when the title has no slug-able characters (the caller decides how to handle that). Single source of truth for the title→filename mapping, shared by the Creator's title-only fallback and the interactive new wizard's recommended-path suggestion.

Source
url_safe_path?(path : String) : Bool

Return true when every segment of path is already URL-safe and does not need auto-sanitization. &quot;URL-safe&quot; here means the segment uses only the RFC 3986 unreserved ASCII set (A-Z a-z 0-9 - . _ ~) plus CJK / Unicode letters, which static hosts serve without percent-encoding surprises.

Source
validate_and_normalize_path!(raw : String) : String

Validate a user-supplied &lt;path&gt; argument to hwaro new and return a normalized form relative to content/ (no prefix), with ./, .., and double-slash segments already collapsed. The result is safe to pass straight into the existing Creator resolution logic, which re-adds the content/ prefix as needed.

Raises ArgumentError when the input is empty, absolute, or would resolve outside content/. Callers (the CLI) wrap the failure in HwaroError(HWARO_E_USAGE) so the classified exit code and --json payload match the rest of the tool.

Source

Instance methods

run(options : Config::Options::NewOptions, config : Models::Config | Nil = nil)
Source