Herodotus Pro / Documentation

Developer Reference

This section is for developers who want to extend, customize, or integrate with Herodotus.


Hooks & Filters

Filters

herodotus_default_settings

Modify the default plugin settings array.

apply_filters( 'herodotus_default_settings', array $defaults )
add_filter( 'herodotus_default_settings', function( $defaults ) {
    $defaults['limit'] = 5;
    return $defaults;
} );

herodotus_shortcode_defaults

Modify the default shortcode attribute values.

apply_filters( 'herodotus_shortcode_defaults', array $defaults )

herodotus_layout

Modify or validate the layout after normalization. Free keeps list, compact and text; unknown requested layouts have already become list. Inspect the original value in $atts to allow a custom layout. Allowing a value alone does not implement a new renderer.

apply_filters( 'herodotus_layout', string $layout, array $atts )
// Allow a custom layout value; add its styling/rendering separately.
add_filter( 'herodotus_layout', function( $layout, $atts ) {
    if ( isset( $atts['layout'] ) && 'my-layout' === $atts['layout'] ) {
        return 'my-layout';
    }
    return $layout;
}, 10, 2 );

herodotus_empty_html

Modify the HTML shown when no events are found.

apply_filters( 'herodotus_empty_html', string $html, array $atts )
add_filter( 'herodotus_empty_html', function( $html, $atts ) {
    return '<p class="my-empty">Nothing happened today.</p>';
}, 10, 2 );

herodotus_header_html

Modify the header HTML rendered above the events grid.

apply_filters( 'herodotus_header_html', string $header_html, array $atts )

herodotus_date_separator_html

Modify the date separator HTML shown between event groups.

apply_filters( 'herodotus_date_separator_html', string $html, string $date, int $post_id )

herodotus_post_classes

Modify the CSS classes array applied to each event card wrapper.

apply_filters( 'herodotus_post_classes', array $classes, int $post_id, array $atts, string $layout )
add_filter( 'herodotus_post_classes', function( $classes, $post_id, $atts, $layout ) {
    $classes[] = 'my-custom-class';
    return $classes;
}, 10, 4 );

herodotus_card_image_html

Modify the <img> tag HTML for the event card thumbnail.

apply_filters( 'herodotus_card_image_html', string $img_html, int $post_id, string $thumb_url, string $title )

herodotus_default_image_url

Modify the fallback image URL used when an event has no featured image.

apply_filters( 'herodotus_default_image_url', string $default_image, int $post_id )

herodotus_show_category

Control whether the category label is shown on an event card.

apply_filters( 'herodotus_show_category', bool $show, WP_Post $post )
add_filter( 'herodotus_show_category', '__return_false' );

herodotus_read_more_html

Modify the "Read more" link HTML.

apply_filters( 'herodotus_read_more_html', string $html, string $permalink, int $post_id )

herodotus_format_date

Modify the formatted date string shown in the date separator.

apply_filters( 'herodotus_format_date', string $date_str, int $day, int $month, int $post_id )

herodotus_show_single_year_badge

Control whether the year badge is shown on single event pages.

apply_filters( 'herodotus_show_single_year_badge', bool $show, int $post_id )

herodotus_merge_params

Modify the merged query parameters after combining shortcode attributes and global settings.

apply_filters( 'herodotus_merge_params', array $merged, array $overrides, array $settings )

herodotus_query_date

Modify the day/month used when querying events.

apply_filters( 'herodotus_query_date', array $date, array $params, DateTime $now )
// $date = [ 'day' => int, 'month' => int ]

herodotus_date_pairs

Modify the array of day/month pairs used in the query (e.g. for "around today" mode).

apply_filters( 'herodotus_date_pairs', array $pairs, array $params, DateTime $now )
// $pairs = [ [ 'day' => int, 'month' => int ], ... ]

herodotus_query_args

Modify the WP_Query arguments before the database query runs.

apply_filters( 'herodotus_query_args', array $query_args, array $params, DateTime $now )

herodotus_query_posts

Modify the posts array returned from the query.

apply_filters( 'herodotus_query_posts', array $posts, array $params )

herodotus_limit_field_description

Add a description string below the "Posts Limit" field in settings.

apply_filters( 'herodotus_limit_field_description', string $description )

herodotus_sanitize_settings

Modify the sanitized settings array before it is saved.

apply_filters( 'herodotus_sanitize_settings', array $sanitized, array $input, array $defaults )

herodotus_admin_shortcode_examples

Modify the list of shortcode examples shown on the Shortcodes tab.

apply_filters( 'herodotus_admin_shortcode_examples', array $examples )

Actions

herodotus_before_container

Fires before the main events container opens.

do_action( 'herodotus_before_container', array $atts, string $layout )

herodotus_before_card

Fires before each event card is rendered.

do_action( 'herodotus_before_card', WP_Post $post, array $atts, string $layout )

herodotus_card_image_overlay

Fires inside the image wrapper - use to add overlays or badges over the image.

do_action( 'herodotus_card_image_overlay', WP_Post $post, string $layout )

herodotus_card_tags

Fires in the card content area - used to render tags (implemented by Pro).

do_action( 'herodotus_card_tags', WP_Post $post )

herodotus_card_body_after

Fires after the card body content (after excerpt and read more).

do_action( 'herodotus_card_body_after', WP_Post $post, string $layout )

herodotus_after_card

Fires after each event card is closed.

do_action( 'herodotus_after_card', WP_Post $post, array $atts, string $layout )

herodotus_after_grid

Fires after the inner grid wrapper closes, before the container closes.

do_action( 'herodotus_after_grid', array $atts, string $layout )

herodotus_after_container

Fires after the main container closes.

do_action( 'herodotus_after_container', array $atts, string $layout )

herodotus_single_tags

Fires on single event pages - used to render tags (implemented by Pro).

do_action( 'herodotus_single_tags', int $post_id, array|false $tags )

herodotus_metabox_fields

Fires inside the date metabox - use to add custom fields.

do_action( 'herodotus_metabox_fields', WP_Post $post )

herodotus_save_post_meta

Fires after Herodotus saves post meta - use to save additional fields.

do_action( 'herodotus_save_post_meta', int $post_id )

herodotus_after_register_taxonomy

Fires after the herodotus_category taxonomy is registered.

do_action( 'herodotus_after_register_taxonomy' )

herodotus_register_settings

Fires during settings registration - use to register additional settings sections and fields.

do_action( 'herodotus_register_settings', string $page_slug, string $option_name, string $option_group )

herodotus_order_options

Fires inside the Sort Order field - use to add custom order options.

do_action( 'herodotus_order_options', string $current )

herodotus_admin_header

Fires in the settings page header area.

do_action( 'herodotus_admin_header' )

herodotus_admin_tab_general

Fires inside the General tab - use to render additional settings fields.

do_action( 'herodotus_admin_tab_general', string $page_slug, string $option_name )

herodotus_admin_tab_display

Fires inside the Display tab.

do_action( 'herodotus_admin_tab_display', string $page_slug, string $option_name )

herodotus_admin_tab_advanced

Fires inside the Advanced tab.

do_action( 'herodotus_admin_tab_advanced', string $page_slug, string $option_name )

herodotus_admin_export_import

Fires in the Data tab, outside the settings <form>. Use to render export/import UI.

do_action( 'herodotus_admin_export_import' )

CSS Classes Reference

Container

Class Element
.herodotus-container Main events wrapper
.herodotus-layout-list List layout modifier
.herodotus-layout-compact Compact layout modifier
.herodotus-empty "No events today" message

Event Card

Class Element
.herodotus-card Individual event card
.herodotus-card__image-wrap Image container
.herodotus-card__body Content area
.herodotus-card__title Event title (heading)
.herodotus-card__excerpt Excerpt paragraph
.herodotus-card__read-more "Read more" link
.herodotus-year-badge Year badge element
.herodotus-card__category-label Category label

Custom CSS Example

/* Change event card background */
.herodotus-card {
    background-color: #f8f9fa;
    border-radius: 8px;
    padding: 20px;
}

/* Style the year badge */
.herodotus-year-badge {
    background-color: #c0392b;
    color: #fff;
    font-size: 14px;
    padding: 2px 8px;
    border-radius: 4px;
}

/* Compact layout adjustments */
.herodotus-layout-compact .herodotus-card {
    padding: 10px;
    margin-bottom: 8px;
}

More CSS Selectors

SelectorElement
.herodotus-gridInner event collection
.herodotus-headerListing heading
.herodotus-date-separatorDate group heading
.herodotus-card__image-linkImage link
.herodotus-card__imageImage element
.herodotus-anniversaryYears-ago or countdown text
.herodotus-layout-textText wrapper
.herodotus-layout-grid-4Four-column grid wrapper
.herodotus-layout-carousel-1Single-card carousel wrapper
.herodotus-layout-timelineTimeline wrapper

Post Meta Fields

KeyMeaning
_herodotus_day / _herodotus_monthRecurring day (1-31) and month (1-12)
_herodotus_year / _herodotus_eraPositive historical year; era BC, AD or empty
_herodotus_mdDerived combined month/day query key
_herodotus_sort_yearDerived signed year, negative for BC
_herodotus_priorityPro priority flag
_herodotus_announce / _herodotus_announce_mdPro upcoming flag and its derived month/day key
_herodotus_source_name / _herodotus_source_urlPro source citation
_herodotus_location_name / _herodotus_location_lat / _herodotus_location_lngPro location name and coordinates

The editor, Quick Edit and Pro importer synchronize the derived date keys. Writes through WordPress metadata functions also queue synchronization before queries, successful REST responses or shutdown. Direct SQL bypasses these hooks.

Querying Events Programmatically

// Get all events for May 15
$events = get_posts([
    'post_type'  => 'herodotus_post',
    'meta_query' => [
        ['key' => '_herodotus_day',   'value' => 15, 'type' => 'NUMERIC'],
        ['key' => '_herodotus_month', 'value' => 5,  'type' => 'NUMERIC'],
    ],
    'posts_per_page' => -1,
]);

For production use, prefer Herodotus_Query::get_posts() which handles caching, sorting and all plugin parameters correctly.


REST API

Standard WordPress Endpoints

Herodotus 1.6.8 supports reading and writing event dates through the standard WordPress REST API. Authenticate as a user who can edit the event and use context=edit when reading date metadata.

GET /wp-json/wp/v2/herodotus_post/{id}?context=edit
POST /wp-json/wp/v2/herodotus_post
POST /wp-json/wp/v2/herodotus_post/{id}

Date fields are returned under meta in edit context. Public view responses omit these fields; public event content remains available through the normal content endpoints. The metadata authorization callback also checks edit_post for writes.

Create an Event

{
  "title": "Moon Landing",
  "status": "publish",
  "meta": {
    "_herodotus_day": 20,
    "_herodotus_month": 7,
    "_herodotus_year": 1969,
    "_herodotus_era": "AD"
  }
}

Send this JSON to the collection POST endpoint using WordPress REST authentication. For an existing event, send only the metadata fields that need changing to its item endpoint.

Date Validation and Synchronization

  • Day: integer 1-31. Month: integer 1-12. Year: integer 1-9999.
  • Era: an empty string, AD or BC. Send an empty string to clear the displayed era suffix.
  • Out-of-range values, fractional integers and unknown era values are rejected. The schema does not validate every impossible calendar combination.
  • An AD year, or a year with blank era, later than the current year may be stored through REST but is excluded from date-based listings. BC accepts years through 9999.
  • Missing required date fields exclude the event from date-based listings. WordPress metadata deletion via null also clears the corresponding derived query key.

The derived _herodotus_md and _herodotus_sort_year keys are recalculated before a successful REST write response. They are not writable REST fields. In active Pro, an existing Upcoming Event also follows a changed date.

Other Metadata Writers

Changes made with WordPress metadata functions, including WP-CLI, are queued. The queue is synchronized before the next Herodotus event query, a related-events query, a completed standard REST write, or at shutdown. If custom code must inspect derived keys before those boundaries, flush the pending queue explicitly:

update_post_meta( $post_id, '_herodotus_day', 21 );
herodotus_sync_queued_date_keys();

Direct SQL writes bypass WordPress metadata hooks and are not covered. The editor, Quick Edit and Pro importer keep their existing save behavior.

Pro Read-Only Endpoint

GET /wp-json/herodotus/v1/posts?date=07-20&limit=5&order=ASC

Active Pro also registers this public GET endpoint for date-based listings. Supported query parameters are limit (default 10), date_mode, date, category, exclude_category and order. It is not an event creation or update route.

Response fieldMeaning
idEvent ID
title, excerpt, content, linkTitle, WordPress excerpt, filtered content and permalink
day, month, yearStored historical date numbers
imageWordPress thumbnail URL, or false
categoriesObject mapping category slugs to names

The response is a JSON array, empty when no events match. Era, source, coordinates and priority are not separate response fields in this Pro endpoint. Its image URL remains thumbnail-sized; responsive card rendering does not change that API response.

Template Override

Single-event pages use the standard WordPress theme hierarchy. For a classic PHP theme, place single-herodotus_post.php in the theme root. For a block theme use the corresponding templates/single-herodotus_post.html block template, or configure the appropriate single-item template in the Site Editor.

The path your-theme/herodotus/single-herodotus_post.php has no special support in this plugin.

For event category archives, the plugin checks theme-root taxonomy-herodotus_category.php and taxonomy-herodotus.php before its own fallback. Pro checks theme-root tag-herodotus.php for event tag archives. These are explicit PHP archive overrides; they are separate from the standard single template hierarchy.

Database Structure

Herodotus does NOT create custom database tables. It uses standard WordPress tables:

WordPress Table Herodotus Usage
wp_posts Stores events (post_type = herodotus_post)
wp_postmeta Stores date fields and other meta
wp_terms Stores category terms
wp_term_taxonomy Category taxonomy relationships
wp_term_relationships Event ↔ Category assignments
wp_options Plugin settings + transient cache

Additional Hooks in 1.6.8

HookArguments after the hook namePurpose
herodotus_random_empty_html$html, $attsEmpty state for the random shortcode
herodotus_anniversary_text$text, $post_idYears-ago or countdown text
herodotus_show_anniversary$show, $post_idCounter visibility
herodotus_show_related$show, $post_idRelated-events visibility
herodotus_related_limit$limit, $post_idRelated count, default 5
herodotus_feed_limit$limitRSS query limit override
herodotus_single_schema$schema, $postSingle event schema
herodotus_admin_tabs$tabs, $has_proSettings tab definitions
herodotus_admin_saveable_tabs$saveable, $tabsTabs that save settings
herodotus_admin_tab_{id}$page_slug, $option_nameRender the named settings tab
herodotus_quick_edit_fieldsNoneExtra date-area UI
herodotus_quick_edit_status_fieldsNoneAdditional Quick Edit flags
herodotus_quick_edit_save$post_idAfter the Quick Edit save
herodotus_pro_export_event$event, $postAdd Pro data to JSON export
herodotus_pro_import_event$post_id, $itemRestore additional imported data
herodotus_pro_source_html$html, $post_idRendered source HTML
herodotus_pro_location_html$html, $post_idRendered location HTML
herodotus_pro_single_countdown_days$daysUpcoming countdown window on a single event

Filters return the modified value. Actions render output or perform a side effect. Match accepted_args to the source signature when registering callbacks. The herodotus_save_post_meta action belongs to the metabox save route; do not assume it covers Quick Edit, import or REST writes. Date-key synchronization for those routes is handled separately. Keep custom forms outside the settings form when using herodotus_admin_export_import.

Responsive Images and Custom HTML

From 1.6.8, card images include responsive srcset and sizes attributes. The herodotus_card_image_html filter and herodotus-card__image class remain available. If replacing the image markup, preserve responsive sources, dimensions, class and relevant attributes. Do not strip them with an unrelated sanitization step.