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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions