Redesigned the href_decorator plugin from a pattern-centric config to a rules-based config (defaults + rules with optional match, collections, attrs). Decoration is limited to links inside <article> elements via Nokogiri DOM selection; navigation, tags, and footers are left unchanged. External/asset/PDF links get defaults everywhere; all links in the posts collection get defaults inside article body only.
defaults (plain hash) and rules (array of rule objects) replacing properties/patterns.match (href regex), optional collections (document collection filter), optional attrs (merge/override).match and collections default to “all” and narrow when specified; attrs merge with defaults; false disables a default; multiple matching rules merge (later wins).<article>) decorated; internal navigation (tags, categories, nav, footers) unchanged._plugins/10_href_decorator.rb and _config.yaml only. No tests (user waiver)._config.yaml — href_decorator.defaults (hash: target, rel), href_decorator.rules (array of entries with match, collections, and/or attrs). Example rules: ^https?://, /assets/, .+\.pdf$ with download: true, and collections: [posts]._plugins/10_href_decorator.rb — Registers :documents, :post_render. Parses document.output with Nokogiri; selects only article a[href]; for each anchor, computes merged attributes from matching rules and collection label; applies attributes via Nokogiri node API. Replaces output only when at least one link was modified. No regex on HTML; all selection/mutation through DOM.bundle exec jekyll build run successfully. Manual checks: post pages have target="_blank" only on links inside <article> (body and cross-links); nav, breadcrumb, tags, and footer links on the same page have no target="_blank". Garden and pages: only external/asset/PDF links in article get decoration. QA semantic review (KISS, DRY, YAGNI, completeness, regression) passed; one trivial doc update (memory-bank wording for article scope).doc.css('article a[href]')) rather than regex. The site already depends on Nokogiri; avoids fragile parsing.<article> assumes post and garden layouts wrap body in that tag; documenting this in the plugin header keeps the contract clear.<article> content counts (and using the DOM to enforce it) closed the gap.None identified for this task.
If “decorate only body links with configurable rules” had been a core requirement from the start, the plugin would have been designed around: parse with Nokogiri, select article a[href], apply rules. Same end state with one less round-trip (no full-document regex pass to discard).
None.