Havenlytics is built to be extended through hooks, filters, and theme template overrides — never by editing plugin files. This guide is the umbrella map of the most common extension points, each with a real example and a link to the deep-dive documentation.
Golden rule: If your customization survives a plugin update, you did it right. Put PHP in your own plugin or your theme’s
functions.php, and template changes in your theme’shavenlytics/folder.
1. Hook into the lifecycle
Run setup once Havenlytics is fully loaded and all services, CPTs, and REST routes are available.
<?php
add_action( 'hvnly_loaded', function () {
// Register your integration here.
} );
See Action Hooks and Plugin Architecture.
2. Modify property data & templates
Change the assembled property data array with the hvnly_property_data filter, remap a field to a custom template with hvnly_field_template_mapping, or override a template file from your theme.
<?php
add_filter( 'hvnly_property_data', function ( $data, $property_id ) {
$data['my_score'] = (int) get_post_meta( $property_id, '_my_score', true );
return $data;
}, 10, 2 );
To override the price card field, copy the plugin’s templates/archive/fields/price.php to your-theme/havenlytics/archive/fields/price.php. See Property Engine, Filter Hooks, and Template Override System.
3. Customize search queries
Add your own meta_query or tax_query conditions to every property listing query.
<?php
add_filter( 'hvnly_property_query_args', function ( $args ) {
$args['meta_query'][] = array(
'key' => '_hvnly_property_featured',
'value' => '1',
'compare' => '=',
);
return $args;
} );
See Search Engine.
4. Add a Workspace verification factor
The Agent Workspace authorization layer is factor-agnostic. Implement VerificationFactorInterface and register it — the two-condition gate picks it up with zero changes to authorization code.
<?php
use HvnlyNab\Workspace\Identity\VerificationFactorInterface;
class My_Phone_Factor implements VerificationFactorInterface {
public function slug() { return 'phone'; }
public function label() { return __( 'Phone verification', 'my-addon' ); }
public function is_required_for_access( $user_id ) { return true; }
public function is_satisfied( $user_id ) {
return '1' === get_user_meta( $user_id, '_my_phone_verified', true );
}
public function state( $user_id ) {
return array( 'satisfied' => $this->is_satisfied( $user_id ) );
}
}
add_filter( 'hvnly_identity_factors', function ( array $factors ) {
$factors[] = new My_Phone_Factor();
return $factors;
} );
See Authentication & Authorization.
5. Add a Workspace navigation view (JavaScript)
The Workspace SPA exposes a view registry. Register a new nav view without touching core.
// In your Workspace-enqueued script:
viewRegistry.registerView( {
id: 'my-view',
path: 'my-view',
title: 'My View',
group: 'tools',
order: 50,
icon: 'star',
component: MyViewComponent,
} );
See Agent Workspace Developer Guide.
6. Register a custom Elementor widget
Extend \Elementor\Widget_Base, return ['havenlytics'] from get_categories(), and add it to both widget maps. Full walkthrough in Elementor Integration.
7. Customize transactional emails
Filter subjects, merge tags, and branding, or override an email template in your theme.
<?php
add_filter( 'hvnly_email_merge_tags', function ( $map, $context ) {
$map['{agency_tagline}'] = 'Your trusted local experts';
return $map;
}, 10, 2 );
See Email System.
8. Register a custom REST controller
The admin REST API resolves its controllers from a filterable class map, so you can add your own controller under hvnlynab/v1.
<?php
add_filter( 'hvnlynab_rest_api_class_map', function ( array $classes ) {
$classes[] = \MyAddon\Api\MyController::class;
return $classes;
} );
Best practices
- Ship customizations in your own plugin or a child theme — never edit Havenlytics core.
- Prefer filters for changing data and actions for side effects.
- Respect the deletion-safety and caching helpers so your add-on plays well with upgrades.
- Namespace your own code and prefix your hooks/meta to avoid collisions with
hvnly_.
Security notes
Security: Any custom REST route or AJAX handler you add must implement a
permission_callback/ nonce + capability check and sanitize every input. ReuseHvnlyNab\Workspace\Security\WorkspaceSecurityfor Workspace-scoped data. See Security.
Common mistakes
- Editing plugin files directly — changes are lost on update.
- Registering an Elementor widget in only one of the two widget maps.
- Forgetting to return the value in a filter callback.
- Adding meta queries that aren’t indexed, hurting archive performance.