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
| Selector | Element |
|---|---|
.herodotus-grid | Inner event collection |
.herodotus-header | Listing heading |
.herodotus-date-separator | Date group heading |
.herodotus-card__image-link | Image link |
.herodotus-card__image | Image element |
.herodotus-anniversary | Years-ago or countdown text |
.herodotus-layout-text | Text wrapper |
.herodotus-layout-grid-4 | Four-column grid wrapper |
.herodotus-layout-carousel-1 | Single-card carousel wrapper |
.herodotus-layout-timeline | Timeline wrapper |
Post Meta Fields
| Key | Meaning |
|---|---|
_herodotus_day / _herodotus_month | Recurring day (1-31) and month (1-12) |
_herodotus_year / _herodotus_era | Positive historical year; era BC, AD or empty |
_herodotus_md | Derived combined month/day query key |
_herodotus_sort_year | Derived signed year, negative for BC |
_herodotus_priority | Pro priority flag |
_herodotus_announce / _herodotus_announce_md | Pro upcoming flag and its derived month/day key |
_herodotus_source_name / _herodotus_source_url | Pro source citation |
_herodotus_location_name / _herodotus_location_lat / _herodotus_location_lng | Pro 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=ASCActive 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 field | Meaning |
|---|---|
| id | Event ID |
| title, excerpt, content, link | Title, WordPress excerpt, filtered content and permalink |
| day, month, year | Stored historical date numbers |
| image | WordPress thumbnail URL, or false |
| categories | Object 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
| Hook | Arguments after the hook name | Purpose |
|---|---|---|
herodotus_random_empty_html | $html, $atts | Empty state for the random shortcode |
herodotus_anniversary_text | $text, $post_id | Years-ago or countdown text |
herodotus_show_anniversary | $show, $post_id | Counter visibility |
herodotus_show_related | $show, $post_id | Related-events visibility |
herodotus_related_limit | $limit, $post_id | Related count, default 5 |
herodotus_feed_limit | $limit | RSS query limit override |
herodotus_single_schema | $schema, $post | Single event schema |
herodotus_admin_tabs | $tabs, $has_pro | Settings tab definitions |
herodotus_admin_saveable_tabs | $saveable, $tabs | Tabs that save settings |
herodotus_admin_tab_{id} | $page_slug, $option_name | Render the named settings tab |
herodotus_quick_edit_fields | None | Extra date-area UI |
herodotus_quick_edit_status_fields | None | Additional Quick Edit flags |
herodotus_quick_edit_save | $post_id | After the Quick Edit save |
herodotus_pro_export_event | $event, $post | Add Pro data to JSON export |
herodotus_pro_import_event | $post_id, $item | Restore additional imported data |
herodotus_pro_source_html | $html, $post_id | Rendered source HTML |
herodotus_pro_location_html | $html, $post_id | Rendered location HTML |
herodotus_pro_single_countdown_days | $days | Upcoming 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.
