Skip to content
Free

PHP hooks reference

Every filter and action in Foliora, in the order they run, with parameters and copy-ready examples.

3 min read Updated

On this page

Foliora exposes a public contract so themes and add-ons can extend the viewer without touching its code. All live hooks use slash-style names: foliora/….

The viewer pipeline#

When a viewer renders, these run in order:

  1. Saved-embed merge (id)
  2. shortcode_atts()
  3. foliora/viewer_atts
  4. Empty-file check
  5. foliora/pre_render_viewer
  6. foliora/before_viewer
  7. Toolbar (foliora/download_url)
  8. foliora/show_branding
  9. foliora/viewer_file_url
  10. foliora/viewer_html

Lifecycle#

foliora/loaded#

Action. Fires once after every Foliora component has initialised. Use it instead of racing plugins_loaded.

add_action( 'foliora/loaded', function () {
	// Foliora classes exist here.
} );

foliora/pro_loaded and foliora/is_pro_active#

An add-on announces itself by defining FOLIORA_PRO_VERSION and firing foliora/pro_loaded on plugins_loaded before priority 20. foliora/is_pro_active (filter, $pro_confirmed) overrides detection; the result is cached for the request.

foliora/feature_enabled#

Filter ( bool $enabled, string $feature_key ). Per-feature gate for add-ons. Runs only when an add-on is active; the default passed in is true.

Viewer#

foliora/viewer_atts#

Filter ( array $atts ). Change any resolved attribute — file, view, theme, size, toggles — after defaults and saved embeds are applied. The empty-file check runs after it, so you can inject a file.

add_filter( 'foliora/viewer_atts', function ( $atts ) {
	if ( is_page( 'catalogue' ) ) {
		$atts['view']  = 'flip';
		$atts['theme'] = 'sepia';
	}
	return $atts;
} );

Foliora's own WPML / Polylang swap runs at priority 5; hook at 10 or later to override it.

foliora/pre_render_viewer#

Filter ( string|null $output, array $atts ). Return any non-null value to replace the PDF viewer entirely (Foliora Pro uses it for EPUB). The result still passes through foliora/viewer_html.

foliora/before_viewer#

Action ( string $instance_id, array $atts ). Echo markup into the viewer's chrome row before the toolbar.

add_action( 'foliora/before_viewer', function ( $instance_id, $atts ) {
	echo '<div class="my-bar" data-for="' . esc_attr( $instance_id ) . '">…</div>';
}, 10, 2 );

foliora/download_url#

Filter ( string $download_url, array $atts ). The Download button's link — send downloads through a tracked or protected endpoint without changing what the viewer renders.

foliora/show_branding#

Filter ( bool $show ). Whether to print the “Powered by Foliora” credit. Default: the Credit link setting (off).

foliora/viewer_file_url#

Filter ( string $file_url, array $atts ). The URL the viewer loads and the no-JavaScript link uses — for signed or proxied URLs.

foliora/viewer_html#

Filter ( string $html, array $atts ). Wrap or post-process the finished markup. Escape anything you add.

add_filter( 'foliora/viewer_html', function ( $html, $atts ) {
	$name = basename( wp_parse_url( $atts['file'], PHP_URL_PATH ) );
	return '<figure class="my-doc"><figcaption>' . esc_html( $name ) . '</figcaption>' . $html . '</figure>';
}, 10, 2 );

foliora/translate_attachment_id#

Filter ( int $attachment_id, int $original ). Last chance to pick a different PDF attachment for the current language.

Search, SEO and accessibility#

HookParametersUse
foliora/extracted_text$text, $pdf_idClean text extracted from a PDF before it is stored.
foliora/extracted_text_max_chars$maxClip length, default 80000.
foliora/search_index$blob, $post_id, $idsCombined text copied onto a post for site search.
foliora/og_image$url, $post_id, $pdf_idThe social-card image.
foliora/schema_digital_document$doc, $pdf_id, $post_idDigitalDocument JSON-LD; return a non-array to drop it.
foliora/pdf_tagged$tagged, $attachment_idOverride the tagged-PDF result.
add_filter( 'foliora/extracted_text', function ( $text, $pdf_id ) {
	return str_replace( 'CONFIDENTIAL', '', $text );
}, 10, 2 );

Front-end JavaScript events and the FolioraViewer API are in DOM events & JavaScript; Pro's hooks in Pro hooks.