WP Manifestindependent plugin directory
manifest / content / bdc-print-pdf

BDC Print PDF (ACF Page Builder)

A WordPress plugin that adds a [bdc_print_pdf] shortcode rendering a "Download PDF" button. Clicking it streams a simplified, one-column PDF of the current post, built from ACF Insight fields and a filtered subset of the page_builder flexible content.

★ 0stars
3.1.0latest · 1mo ago

Install

Download source zip No release zip yet

This is the repository archive. It installs, but the folder name will carry the branch suffix and updates will not flow.

Install straight from GitHub with WP-CLI:

wp plugin install https://github.com/bonsai-systems/bdc-print-pdf/archive/refs/heads/main.zip
Updates itself. It ships its own updater (Plugin Update Checker), so new versions appear under Dashboard → Updates.

Bonsai Print PDF (ACF Page Builder)

A WordPress plugin that adds a [bdc_print_pdf] shortcode rendering a "Download PDF" button. Clicking it streams a simplified, one-column PDF of the current post, built from ACF Insight fields and a filtered subset of the page_builder flexible content.

Features

  • [bdc_print_pdf label="Download PDF" class="bdc-print-pdf-button"] shortcode — only renders on singular posts of an eligible post type (see "Eligible post types" below).
  • PDF generation via the bundled Dompdf library (no Composer dependency at runtime — the dompdf/ folder is vendored directly).
  • Content pulled from:
    • Top-level ACF fields: insight_headline, insight_introduction, associated_authors (relationship field) — rendered as a header with title, intro, author photos and byline.
    • legacy_content ACF field, if present.
    • The page_builder ACF Flexible Content field — only insights_content_module rows are included, and only rows with content_type of content-text, content-quote, content-table, or content-type-table. Video, image, and two-image blocks are intentionally skipped to keep the PDF compact.
    • Ninja Tables shortcodes ([ninja_tables id="..."]) found in text or table blocks are expanded to static HTML tables — read directly from the wp_ninja_table_items DB table where possible, falling back to do_shortcode() output.
  • Footer added to every PDF page via the Dompdf canvas: a clickable "Read the full insight" link (bottom-left) and page_num / page_count (bottom-right).
  • First-page logo pulled from the ACF Options field site_main_logo.
  • Looks for a dedicated print stylesheet at assets/css/core/print-pdf.css in the active child theme first, then the parent theme, and loads it via <link> if found.
  • Request handling is via a custom query var (bdc_print_pdf=1) on template_redirect. The URL is stable per post (no nonce, no expiry) — see "PDF endpoint behaviour" below.

Eligible post types

The PDF endpoint only serves singular posts of an allowed post type, filterable via bdc_print_pdf_post_types (default: array( 'post' )):

add_filter( 'bdc_print_pdf_post_types', function ( $types ) {
    return array( 'post', 'insights' );
} );

Requests against any other post type (or content that doesn't resolve to a valid post) return 404. This plugin ships to multiple Bonsai sites via the same GitHub release, so this is a filter rather than a hard-coded post type — confirm the correct value for each site before relying on the default.

PDF endpoint behaviour

As of 3.1.0, the endpoint no longer uses a nonce. It previously did (bdc_print_pdf_{$post_id}, verified in template_redirect), but since the endpoint only ever renders a published, publicly-viewable post, there was no state-changing action for the nonce to protect, and it rotated the URL every 12–24 hours. That made the URL uncacheable and, once an expired-nonce URL got indexed, caused it to 500 indefinitely (a bare wp_die() defaults to HTTP 500) — Google recrawls a 500 forever on the assumption it's transient, which on the Dixcart site alone produced ~6,200 indexed, permanently-broken PDF URLs.

Current behaviour:

Request Response
?bdc_print_pdf=1 on an eligible post 200, application/pdf, Cache-Control: public, max-age=… (filterable via bdc_print_pdf_cache_seconds, default 1 hour), X-Robots-Tag: noindex, nofollow
?bdc_print_pdf=1&bdc_pp_nonce=<anything> 410 Gone — legacy nonce URLs are permanently retired, regardless of whether the nonce value would still verify
?bdc_print_pdf=1 on a non-eligible post type, or an invalid post 404
Dompdf library missing 404, with the underlying cause logged via error_log()

No code path returns a 5xx. Every response — success or failure — carries X-Robots-Tag: noindex, nofollow, since the PDF duplicates the article it's generated from and shouldn't compete with it in search.

Requirements

  • WordPress 6.0+
  • PHP 8.0+
  • ACF (Advanced Custom Fields / ACF Pro) — the plugin degrades gracefully to raw post content if ACF is not active, but the Insight-specific header/fields require it.
  • The dompdf/ folder must be present inside the plugin directory (already vendored in this repo).

Usage

  1. Activate the plugin.
  2. Add [bdc_print_pdf] to a template or the page builder where you want the download button to appear.
  3. Optional shortcode attributes:
    • label — button text (default: Download PDF)
    • class — CSS class on the <a> tag (default: bdc-print-pdf-button)

Data / Fields Used

No custom options are stored by this plugin — it only reads existing ACF field data at request time:

Field Type Used for
insight_headline Text PDF header title (falls back to post title)
insight_introduction Textarea PDF header intro
associated_authors Relationship Author photos + byline links
legacy_content WYSIWYG Optional legacy content block
page_builder Flexible Content Filtered insights_content_module rows
site_main_logo Image (Options page) First-page logo

Security Note

Field values (insight_headline, insight_introduction, legacy_content, module text/quote/table content) are output largely as-authored (via wp_kses_post() or, for the headline/intro, directly) so that editor-authored HTML formatting survives into the PDF. Access to author these fields is restricted to users who can edit the relevant post type — there is no public-facing input on this plugin. The PDF endpoint itself is read-only (it renders an already-public post) and unauthenticated by design; see "PDF endpoint behaviour" above for why it has no nonce.

Updates

Ships with YahnisElsts/plugin-update-checker (installed via Composer, vendor/ committed) pointed at github.com/Bonsai-Systems/bdc-print-pdf. Sites with the plugin installed will see updates in Plugins in wp-admin, same as bonsai-code-injector and bonsai-maintenance.

To ship a new version:

  1. Bump the Version: header and the BDC_PP_VERSION constant in bdc-print-pdf.php, and add a CHANGELOG.md entry.
  2. Commit and push to main.
  3. Publish a GitHub Release tagged with the new version (release-assets mode is enabled, so attach a zip of the plugin folder — plain source-archive tags won't be picked up).

Sites check for updates every 6 hours ($checkPeriod argument to buildUpdateChecker()), or immediately if an admin clicks "Check again" on the Plugins screen.

Releases

1 release.

Tag
Published
3.1.0 latest
Sep 22, 2026 1mo ago

These releases are tags only. The author does not attach a packaged zip, so there are no download counts to report.