Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Statamic Bard Footnotes Laravel Package

goldnead/statamic-bard-footnotes

A Statamic addon that adds footnote support to Bard rich text fields. Editors insert inline references and the addon renders a clean, linked footnotes list on the front end, with sensible defaults and easy customization for both content editors and developers.

View on GitHub
Deep Wiki
Context7

Getting Started

  • Install the addon with Composer, then publish any config/assets if the package ships them (php artisan vendor:publish); run npm run build/npm run dev in your site if the addon publishes Vue/JS assets that need to be compiled into your Bard set.
  • First place to look is the Bard field's set configuration — footnotes are driven by a Bard field that can cite sources, so confirm which set(s) in resources/fieldsets/*.yaml (or the blueprint) should enable footnotes, then open the field in the control panel and add a citation.
  • The README is the primary reference: it documents the "Rendering a Bard field in parts" workflow and the footnotes.js helpers, which is where most day-to-day work will happen.
  • First real use case: add a citation in the Bard editor, confirm the Sources (N) bar appears under the editor, click Go to citation / Next citation to verify scrolling and highlighting, then click Edit to change a source text/link and watch every occurrence update live.
  • Then render the field on the front end: number the field once with Footnotes::number() and convert with Augmentor::convertToHtml(), mirroring the pattern in the README, and check that fnref-n appears only once for repeated citations.

Implementation Patterns

Full-field rendering (the simple case). Number the Bard value once via Footnotes::number() and pass the result to Augmentor::convertToHtml(). Keep the numbered value as the single source of truth for the request — do not re-number per partial.

Rendering a Bard field in parts. The v2.1.0 headline workflow:

  1. Call Footnotes::number() on the whole field first. This is idempotent — a fully numbered document comes back unchanged, including its first flags.
  2. Split the numbered document into your parts (columns, blocks, page sections).
  3. Render each part through Augmentor::convertToHtml().

Because numbering happens up front, counters continue across parts and fnref-n is emitted only on the field-wide first occurrence. Avoid the old pattern of numbering inside each part loop; that restarted at 1 per part and broke anchors.

Editor-side integration. The Sources panel is mounted as a ProseMirror plugin view via TipTap's VueRenderer, so it inherits the same app context and provides as a node view. Practical implications:

  • The panel sits immediately after the editor frame and before core's footer toolbar; don't fight that order with CSS or custom toolbars.
  • In fullscreen it becomes a card under the editor card and is rebuilt on enter/leave — treat the panel as ephemeral, not stateful across fullscreen toggles.
  • Fields without footnotes mount nothing, so conditional layout around the editor is unnecessary.

Using the pure helpers. footnotes.js exports hasFootnotes, nextCitation, isHttpUrl, reusedCount (now with a wholeSource mode), and citationHighlightPlugin with the setCitationHighlight command. These are tested against a real ProseMirror schema, so they're safe to reuse in custom Vue components, toolbar buttons, or export/preview tooling — for example, wiring your own "jump to next citation" control by calling nextCitation.

Highlighting programmatically. setCitationHighlight is deliberately not recorded for undo, which makes it the right tool for transient UI (hover previews, search results, deep links into a citation). Pair it with the highlight plugin when you build a custom citation navigator.

Localisation. Ship or override the en/de strings — sources_heading, cited_count, cited_times, open_link, go_to_citation, next_citation, edit, edit_source, apply_source — via your normal translation/config override path when supporting other locales.

Gotchas and Tips

  • Number before splitting, always. Footnotes::number() is idempotent and preserves first flags, but a partly numbered document is re-numbered from scratch. If any middleware, cache layer, or partial render touches only a slice before you number, you'll silently lose existing numbers.
  • Sources are never merged or removed in the panel. Editing a source rewrites every place that source is cited; there is no remove action — footnotes are deleted in the text itself. Teach editors this, or they'll hunt for a delete button.
  • Read-only fields have no Edit. Don't write UI or tests that assume the edit button exists on every field.
  • Undo won't clear highlights set by setCitationHighlight. Clear them explicitly when your transient UI closes, otherwise a highlight can linger after an undo stack change.
  • Fullscreen remounts the panel. Any DOM references, observers, or event listeners attached to the panel must be re-established; don't cache the panel element across fullscreen transitions.
  • "Live on every change, in number order" means the panel re-sorts as citations move. If you write assertions against the panel, assert against number order, not insertion order.
  • reusedCount semantic change. The new wholeSource option changes counting scope; audit any custom code calling reusedCount to confirm which behaviour it expects.
  • Missing strings vs. missing features. With only en/de shipped, an unlocalised site may render raw keys in the panel — verify sources_heading and friends resolve before reporting a bug.
  • Debugging rendering issues: check first whether fnref-n appears more than once for the same source (numbering ran per part) and whether counters restart at 1 (numbering ran after splitting). Both point to the same root cause.
  • Extension point to watch: the ProseMirror plugin view + pure helpers are the stable seams. Prefer composing your own plugin/commands over patching the mounted Vue component, which is recreated on fullscreen and may change internally.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route