Skip to content

Pluggable file-handler support: make Plerd::Post abstract with an extension registry #65

Description

@jmacdotorg

Summary

Make Plerd able to build a post from any kind of source file, not just Markdown, by turning Plerd::Post into an abstract base class and letting extensions register Plerd::Post subclasses against the file extensions they handle. Markdown becomes the default, built-in handler.

This grew out of #29 by @doddo, which began as "let me plug in a JPEG handler" (InstaPlerd — parsing JPEGs into image posts with filters; live at petter.re) and evolved, in a good back-and-forth, into a general design. The valuable artifact from that PR is the converged design, captured below; the diff itself predates major internal changes (1.900) and is a reference rather than something to rebase. Thanks to @doddo for the work and the design discussion.

This is a major-version–scale refactor (it abstracts the core Post class), best implemented deliberately rather than merged from the 2018 branch.

Converged design

  • Registry on Plerd — an attribute mapping file extensions → Plerd::Post subclasses. Default has two entries: .md and .markdownPlerd::Post::Markdown.
  • Plerd::Post becomes abstract — it holds the attributes and methods common to all post types; type-specific methods are stubs that die if a subclass doesn't override them.
  • Self-registration — the base class exposes the list of extensions a handler claims plus a class method to register itself with its Plerd object.
  • Plerd::Post::Markdown — a new subclass holding all the current Markdown-specific logic, shipped as the default handler.
  • Authoring an extension is then: subclass Plerd::Post, override/add methods, declare its extensions, and register on load (via config).

Related simplification (agreed in the thread)

Retire the File::ChangeNotify allowlist regex. Today the watcher matches an allowlist of post-file patterns. Instead, ignore a small denylist (dotfiles, tilde/backup files, extensionless files) and treat everything else as a candidate post: hand each file to the subclass registered for its extension, or skip with a warning if none is registered. @doddo confirmed this is flexible enough for the InstaPlerd use case.

Work needed beyond #29

  1. Reimplement against current master, not rebase. The branch predates the publication_*docroot rename, Minilla packaging, and the 1.900 changes below.
  2. Incremental publishing. 1.900 added incremental republishing via publish_file and a daemon that watches the source dir. File→handler resolution (the new registry + denylist) must drive both publish_all and publish_file, replacing the watcher's old compound regex.
  3. Atomic writes. Subclass publish methods must use the atomic temp-file-then-rename() helpers introduced in 1.900, so the abstraction doesn't reintroduce non-atomic writes.
  4. Config surface. Decide how users register an extension class in plerd.conf (e.g. a list of handler module names to load and register).
  5. Tests. Rework Extension support #29's t/lib/TestExtension.pm + t/source_model/extension.dm into the new abstract structure: a test handler for a non-Markdown extension, asserting it's resolved, instanced, and published.

Prior art

PR #29 (the original diff and the full design discussion). @doddo's working references: InstaPlerd (JPEG handler) and the ExtendedPlerd/Watcher classes in tuvix, which demonstrate the registry + compound-regex approach in production.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions