Hooks & Filters

Hooks & Filters

Customize Academic References behavior using WordPress action hooks and filters.

Reference Lifecycle

Before Reference Save

/**
 * Fires before a reference is saved.
 *
 * @param array $reference_data Reference data being saved.
 * @param int   $post_id        Post ID (0 for new references).
 */
do_action( 'abt_before_reference_save', $reference_data, $post_id );

After Reference Save

/**
 * Fires after a reference is saved.
 *
 * @param int   $post_id        Saved reference post ID.
 * @param array $reference_data Reference data that was saved.
 * @param bool  $update         Whether this was an update.
 */
do_action( 'abt_after_reference_save', $post_id, $reference_data, $update );

Before Reference Delete

/**
 * Fires before a reference is deleted.
 *
 * @param int $post_id Reference post ID being deleted.
 */
do_action( 'abt_before_reference_delete', $post_id );

Filter Reference Data

/**
 * Filter reference data before saving.
 *
 * @param array $data    Reference data array.
 * @param int   $post_id Post ID (0 for new).
 * @return array Modified reference data.
 */
add_filter( 'abt_reference_data', function( $data, $post_id ) {
    // Modify reference data
    $data['custom_field'] = 'value';
    return $data;
}, 10, 2 );

Auto-Cite Hooks

Before Fetch

/**
 * Fires before fetching data from external source.
 *
 * @param string $identifier Identifier being looked up.
 * @param string $type       Identifier type (doi, pmid, isbn).
 */
do_action( 'abt_before_autocite_fetch', $identifier, $type );

Filter Fetch Results

/**
 * Filter auto-cite results before processing.
 *
 * @param array  $data       Fetched reference data.
 * @param string $identifier Original identifier.
 * @param string $type       Identifier type.
 * @return array Modified data.
 */
add_filter( 'abt_autocite_result', function( $data, $identifier, $type ) {
    // Enhance or modify fetched data
    if ( $type === 'doi' ) {
        $data['custom_source'] = 'DOI lookup';
    }
    return $data;
}, 10, 3 );

Add Custom Fetcher

/**
 * Register custom identifier fetcher.
 *
 * @param array $fetchers Registered fetchers.
 * @return array Modified fetchers array.
 */
add_filter( 'abt_autocite_fetchers', function( $fetchers ) {
    $fetchers['custom_id'] = array(
        'label'    => 'Custom ID',
        'pattern'  => '/^CUS-\d+$/',
        'callback' => 'my_custom_fetcher_function',
    );
    return $fetchers;
} );

function my_custom_fetcher_function( $identifier ) {
    // Fetch and return reference data
    return array(
        'type'  => 'article',
        'title' => 'Fetched Title',
        // ...
    );
}

Citation Rendering

Filter Citation Output

/**
 * Filter rendered citation HTML.
 *
 * @param string $html          Rendered citation HTML.
 * @param array  $reference_ids Array of reference IDs.
 * @param array  $options       Citation options.
 * @return string Modified HTML.
 */
add_filter( 'abt_citation_html', function( $html, $reference_ids, $options ) {
    // Add wrapper or modify output
    return '' . $html . '';
}, 10, 3 );

Filter Citation Data

/**
 * Filter citation data before rendering.
 *
 * @param array $citations Array of citation data.
 * @param int   $post_id   Post ID where citation appears.
 * @return array Modified citations.
 */
add_filter( 'abt_citation_data', function( $citations, $post_id ) {
    // Modify citation data
    return $citations;
}, 10, 2 );

Bibliography Rendering

Filter Bibliography Output

/**
 * Filter rendered bibliography HTML.
 *
 * @param string $html       Rendered bibliography HTML.
 * @param array  $references Array of reference data.
 * @param array  $options    Bibliography options.
 * @return string Modified HTML.
 */
add_filter( 'abt_bibliography_html', function( $html, $references, $options ) {
    // Modify bibliography output
    return $html;
}, 10, 3 );

Filter Bibliography Entries

/**
 * Filter individual bibliography entry.
 *
 * @param string $entry        Formatted entry HTML.
 * @param array  $reference    Reference data.
 * @param string $style        Citation style ID.
 * @return string Modified entry.
 */
add_filter( 'abt_bibliography_entry', function( $entry, $reference, $style ) {
    // Add custom data to each entry
    $entry .= 'ID: ' . $reference['id'] . '';
    return $entry;
}, 10, 3 );

Before Bibliography Render

/**
 * Fires before bibliography is rendered.
 *
 * @param array $reference_ids IDs of references to include.
 * @param int   $post_id       Post ID containing bibliography.
 */
do_action( 'abt_before_bibliography_render', $reference_ids, $post_id );

Citation Styles

Filter Available Styles

/**
 * Filter list of available citation styles.
 *
 * @param array $styles Array of style definitions.
 * @return array Modified styles array.
 */
add_filter( 'abt_available_styles', function( $styles ) {
    // Add custom style
    $styles['my-custom-style'] = array(
        'name'     => 'My Custom Style',
        'category' => 'author-date',
        'csl_path' => '/path/to/my-style.csl',
    );
    return $styles;
} );

Filter Style Selection

/**
 * Filter the selected citation style.
 *
 * @param string $style_id  Selected style ID.
 * @param int    $post_id   Post ID (if context available).
 * @return string Style ID to use.
 */
add_filter( 'abt_selected_style', function( $style_id, $post_id ) {
    // Use different style for certain post types
    if ( get_post_type( $post_id ) === 'journal_article' ) {
        return 'apa-7th-edition';
    }
    return $style_id;
}, 10, 2 );

Import/Export

Filter Import Data

/**
 * Filter imported reference data.
 *
 * @param array  $data   Reference data from import file.
 * @param string $format Import format (bibtex, ris, csl-json).
 * @return array Modified data.
 */
add_filter( 'abt_import_reference_data', function( $data, $format ) {
    // Normalize or enhance imported data
    return $data;
}, 10, 2 );

After Import Complete

/**
 * Fires after import completes.
 *
 * @param array  $results  Import results (imported, skipped, errors).
 * @param string $format   Import format.
 * @param array  $options  Import options.
 */
do_action( 'abt_after_import', $results, $format, $options );

Filter Export Data

/**
 * Filter reference data before export.
 *
 * @param array  $data   Reference data to export.
 * @param string $format Export format.
 * @return array Modified data.
 */
add_filter( 'abt_export_reference_data', function( $data, $format ) {
    // Remove or modify fields for export
    unset( $data['internal_notes'] );
    return $data;
}, 10, 2 );

Frontend Hooks

Dashboard Content

/**
 * Add content to user dashboard.
 *
 * @param int $user_id Current user ID.
 */
add_action( 'abt_dashboard_after_references', function( $user_id ) {
    echo '
Custom content
'; } );

Submission Form

/**
 * Add fields to submission form.
 */
add_action( 'abt_submission_form_fields', function() {
    echo '
'; echo ''; echo ''; echo '
'; } ); /** * Process custom submission fields. * * @param int $reference_id Saved reference ID. * @param array $form_data Submitted form data. */ add_action( 'abt_after_submission_save', function( $reference_id, $form_data ) { if ( isset( $form_data['custom_field'] ) ) { update_post_meta( $reference_id, '_custom_field', sanitize_text_field( $form_data['custom_field'] ) ); } }, 10, 2 );

REST API Hooks

Filter API Response

/**
 * Filter REST API response for references.
 *
 * @param WP_REST_Response $response Response object.
 * @param WP_Post          $post     Reference post.
 * @param WP_REST_Request  $request  Request object.
 * @return WP_REST_Response Modified response.
 */
add_filter( 'abt_rest_prepare_reference', function( $response, $post, $request ) {
    // Add custom data to API response
    $response->data['custom_field'] = get_post_meta( $post->ID, '_custom_field', true );
    return $response;
}, 10, 3 );

Custom API Endpoints

/**
 * Register custom REST API endpoint.
 */
add_action( 'rest_api_init', function() {
    register_rest_route( 'abt/v1', '/custom-endpoint', array(
        'methods'  => 'GET',
        'callback' => 'my_custom_endpoint_handler',
        'permission_callback' => function() {
            return current_user_can( 'read' );
        }
    ) );
} );

Sync Hooks

Before Zotero Sync

/**
 * Fires before Zotero sync runs.
 *
 * @param string $user_id Zotero user ID.
 */
do_action( 'abt_before_zotero_sync', $user_id );

After Sync Item

/**
 * Fires after each item is synced.
 *
 * @param int    $reference_id Local reference ID.
 * @param string $item_key     Zotero item key.
 * @param string $action       Sync action (create, update, delete).
 */
do_action( 'abt_zotero_sync_item', $reference_id, $item_key, $action );

Admin Hooks

Settings Page

/**
 * Add custom settings section.
 */
add_action( 'abt_settings_sections', function() {
    add_settings_section(
        'my_custom_section',
        'Custom Settings',
        'my_section_callback',
        'abt-settings'
    );
} );

Admin Notices

/**
 * Display admin notices on plugin pages.
 */
add_action( 'abt_admin_notices', function() {
    echo '

Custom notice

'; } );

Utility Functions

Check if Reference Exists

// By DOI
$exists = abt_reference_exists_by_doi( '10.1234/example' );

// By any identifier
$exists = abt_reference_exists_by_identifier( $identifier, $type );

Get Formatted Citation

$citation = abt_get_formatted_citation( $reference_id, 'apa-7th-edition' );

Get Reference Data

$data = abt_get_reference_data( $reference_id );

Best Practices

  1. Use namespaced functions to avoid conflicts
  2. Check hook priority when multiple modifications needed
  3. Cache expensive operations in filters
  4. Validate and sanitize all data
  5. Document custom hooks for other developers

Next Steps

Last updated: January 31, 2026