Implementing Mozilla's PDF Javascript Viewer by BBCode Tags
Written by Chipper (Andrew Egerszegi) with Claude.ai
Compatibility: SMF 2.0.x & SMF 2.1.x
Description and Notes
Displays both locally stored and attached PDF files in posts using [pdf][/pdf] or [pdf=n][/pdf] tags, rendered with abundled, self-hosted copy of Mozilla's PDF.js viewer in an <iframe>.
* Three ways to use the tag:
* [pdf]https://example.com/file.pdf[/pdf]
- displays a locally stored pdf file in web root
* [pdf=nnnn]
- displays the database attachment by it's real "nnnn"
* [pdf=autodisplay][/pdf]
- displays every PDF attached to this post automatically
* [pdf=noautodisplay][/pdf]
- stops automatic displaying (default)
This package never edits Subs.php, Subs-Editor.php, or any other core file, on either SMF branch. The pdf tag, its editor toolbar button, and the auto-detect lookup are all added entirely through SMF's own integration hooks (integrate_bbc_codes, integrate_bbc_buttons, integrate_pre_parsebbc)
* On SMF 2.0.x, where hook auto-loading isn't available, registration is done via a small install-time script that registers each hook by name and adds the plugin file to the pre-include list, checking for existing entries first so a reinstall never duplicates anything
Uninstalling reverses only these entries and leaves every other mod's hooks untouched.
* On SMF 2.1.x, registration uses the standard declarative <hook>
package action. The Package Manager handles registration,a clean removal on its own.
Because nothing here is a text patch against a core file, there is no upgrade/downgrade risk against other mods that might also touch Subs.php or Subs-Editor.php, and uninstalling always cleanly restores the forum to its exact pre-install state.
PDF.js runs entirely client-side. The only network request it makes is to fetch the PDF from the URL you gave the tag and nothing is sent to a third party.
The bundled pdfjs/ folder ships with its own .htaccess, setting the correct MIME type for .mjs/.wasm/.map files, so the PDF.js module worker loads correctly out of the box.
To do:
2.0 is stable
2.1 has some bugs
1. missing button in editor
2. auto loses then pdf line !
Will display PDF files:
1. by URL to web root
2. by it's real database id numbet
3. automatically when attttached to this post
To disable auto-displaynano +690 /var/www/html/Themes/default/Display.template.phpcomment this out like shown below:
// if (!empty($attachment['is_pdf']))
// {
// echo '
// <iframe src="', $settings['theme_url'], '/pdfjs/web/$
// }
Modifying the PDF Viewer defaults:
To set the scroll mode (`ScrollMode.PAGE = 3` — that's "one page at a time, scroll/navigate between them" (what you want, instead of continuous vertical which is `VERTICAL = 0`).
nano +4435 /var/www/html/Themes/default/pdfjs/web/viewer.mjsChange `-1` → `3` (shown below)
scrollModeOnLoad: {
value: 3,
kind: OptionKind.VIEWER + OptionKind.PREFERENCE
},
Leave `spreadModeOnLoad` at `-1` (that controls side-by-side two-page spreads, unrelated to what you want). Reload a PDF after saving and it should open one page at a time with prev/next navigation instead of the continuous scroll.
Debugging the mod:
nano /var/www/html/Sources/Display.phpFind:
loadAttachmentContext(), right after where
$attachmentData[$i] = array( is built, before the
// If something is unapproved we'll note it so we can sort them. line)
Insert:
"
@file_put_contents($boarddir . '/pdfbbc_autotrace.log', date('Y-m-d H:i:s') . ' AUTO-EMBED LOOP: ' . var_export($attachment, true) . "\n", FILE_APPEND);"
If
$boarddir isn't already in that list, insert in the variable into the line below:
global $modSettings, $context,
$boarddir, ...
Testing:
Display by URL to its webroot filenameDisplay by it's database id[pdf=4790][/pdf]
Display every attachment automatically[pdf=autodisplay][/pdf]