Calorie Calculator — developer hooks
Use these WordPress actions/filters and front-end events to extend Calorie Calculator (Pro and Free) from a theme or custom plugin without editing plugin files.
Prefix: calcal_ (PHP) and calcal: (JavaScript).
Calculation (BMR / TDEE) runs in the browser. PHP hooks cannot change the maths mid-calc; use JS events for that moment, or alter markup/email/PDF/leads on the server.
Quick start (PHP)
Place this in a custom plugin or your child theme’s functions.php:
add_action( 'calcal_lead_created', function ( $post_id, $meta, $form_data ) {
// e.g. push to your CRM, Slack, or custom table.
error_log( 'CalCal lead #' . (int) $post_id . ' email=' . ( $meta['email'] ?? '' ) );
}, 10, 3 );
add_filter( 'calcal_calculator_html', function ( $html, $atts ) {
return '<div class="my-brand-wrap">' . $html . '</div>';
}, 10, 2 );
Calculator shortcode / embed
Fired for the [calorie_calculator] shortcode path (and Block / Elementor output that uses the same path).
| Hook | Type | Arguments | Notes |
|---|
calcal_calculator_atts | filter | $atts, $user_atts, $content | After defaults / site settings are resolved, before enqueue + render. |
calcal_before_calculator | action | $atts | Before template output. |
calcal_calculator_html | filter | $html, $atts | After template render; return markup. |
calcal_after_calculator | action | $atts, $html | After HTML is filtered (shortcode still returns $html). |
Pro only — table shortcodes
| Hook | Type | Arguments |
|---|
calcal_foods_table_atts | filter | $atts, $user_atts, $content |
calcal_foods_table_html | filter | $html, $atts |
calcal_exercises_table_atts | filter | $atts, $user_atts, $content |
calcal_exercises_table_html | filter | $html, $atts |
Example — force metric units on every embed:
add_filter( 'calcal_calculator_atts', function ( $atts ) {
$atts['unit'] = 'metric';
return $atts;
} );
Leads / usage logs
When a visitor submits the calculator and logging is enabled, a private calculator_log post is stored.
| Hook | Type | Arguments | Notes |
|---|
calcal_lead_meta | filter | $meta, $form_data | Sanitised meta before wp_insert_post. Return an array. |
calcal_lead_created | action | $post_id, $meta, $form_data | After a successful log insert. Best place for custom CRM sync. |
$meta typically includes: first_name, last_name, email, age, gender, height, weight, activity_factor, bmr (TDEE), basal_bmr, bmi, bmi_category, unit, and on Pro also macros, body_fat, formula_used, user_id when logged in.
Webhooks
| Hook | Type | Arguments | Notes |
|---|
calcal_webhook_payload | filter | $body_data, $payload | Full JSON body (includes event, site, timestamp + lead fields) before wp_remote_post. |
add_filter( 'calcal_webhook_payload', function ( $body, $payload ) {
$body['source'] = 'calorie-calculator';
return $body;
}, 10, 2 );
Integrations (Pro)
ConvertKit / HubSpot dispatch (after log create, when email is present):
| Hook | Type | Arguments |
|---|
calcal_integrations_lead | filter | $lead, $meta, $post_id |
calcal_before_integrations | action | $lead, $meta, $post_id |
calcal_after_integrations | action | $lead, $meta, $post_id |
$lead keys: email, first_name, last_name, consent.
Result email (Pro; Free has subject/body filters only)
| Hook | Type | Arguments | Notes |
|---|
calcal_email_context | filter | $context, $recipient, $person, $calc, $result_html | Token map ({user_name}, {result}, …). Pro. |
calcal_email_subject | filter | $subject, $context, $plugin | |
calcal_email_body | filter | $body, $context, $plugin | HTML body before wp_mail. |
add_filter( 'calcal_email_subject', function ( $subject ) {
return 'Your calorie plan from ' . get_bloginfo( 'name' );
} );
PDF download (Pro)
| Hook | Type | Arguments |
|---|
calcal_pdf_filename | filter | $filename, $person_data, $calculator_data |
calcal_pdf_person_data | filter | $person_data, $calculator_data |
calcal_pdf_message | filter | $message, $person_data, $calculator_data |
calcal_pdf_generated | action | $file_url, $file_path, $person_data, $calculator_data |
Filenames must end in .pdf (unsafe values fall back to a safe default).
Front-end JavaScript events
Events fire on document as both:
- jQuery:
jQuery( document ).on( 'calcal:…', function ( e, detail ) { … } ); - Native:
document.addEventListener( 'calcal:…', function ( e ) { console.log( e.detail ); } );
| Event | When | detail (typical) |
|---|
calcal:result_shown | Results HTML displayed (or email-gated placeholder) | shown, gated, formData, resultHtml (if shown), form, resultEl |
calcal:lead_submitted | AJAX log request succeeded | unit (us \ | metric), formData, form |
calcal:form_cleared | Clear / reset | form |
Legacy (still fired): calcalpro_form_cleared (jQuery only; second argument is the jQuery form).
document.addEventListener( 'calcal:result_shown', function ( e ) {
if ( ! e.detail || ! e.detail.shown ) {
return;
}
// e.g. analytics, GTM dataLayer push
window.dataLayer = window.dataLayer || [];
window.dataLayer.push( { event: 'calcal_result', unit: e.detail.formData && e.detail.formData.unit } );
} );
Stability
- Prefer the
calcal_* / calcal: names above for new code. - Do not rely on Freemius SDK hooks (
ccp_fs_loaded, $fs->…) for product features. - Hook signatures may gain extra trailing arguments in later versions; always declare the arity you need (
add_action( …, 10, 3 )).
For system info and settings backup, see Calorie Calculator → Tools in wp-admin, or the Tools & support section of the documentation hub.
Product documentation: Calorie Calculator Pro documentations
Contact: wp.zubaer.com/contact