Features

Template Override Guide

This article covers every overridable template in KiviCare (core) and KiviCare Pro, where each template lives, what data variables it receives, and how to safely override it from your child theme without touching plugin files.


How the Override System Works

All print/PDF templates use a three-level lookup — the first file found wins:

1. your-child-theme/kivicare/<TemplateName>.php   ← your customisation
2. your-parent-theme/kivicare/<TemplateName>.php  ← theme-level fallback
3. wp-content/plugins/<plugin>/templates/<TemplateName>.php  ← plugin default

Rule: Never edit files inside wp-content/plugins/. Copy the template to your child theme and edit that copy. Plugin updates will not touch your child theme.


Quick Reference

Template FilePluginOverride Path (child theme)Output
KCInvoicePrintTemplate.phpkivicare-clinic-management-systemkivicare/KCInvoicePrintTemplate.phpPDF
KCBillPrintTemplate.phpkivicare-prokivicare/KCBillPrintTemplate.phpPDF
KCEncounterPrintTemplate.phpkivicare-prokivicare/KCEncounterPrintTemplate.phpPDF
KCPrescriptionPrintTemplate.phpkivicare-prokivicare/KCPrescriptionPrintTemplate.phpPDF
PrescriptionEmailTable.phpkivicare-clinic-management-system(hook-based, see below)HTML email
html-kc-dashboard.phpkivicare-clinic-management-system(hook-based, see below)Dashboard HTML shell

Template 1 — Appointment Invoice (KCInvoicePrintTemplate.php)

Plugin: kivicare-clinic-management-system
Source: wp-content/plugins/kivicare-clinic-management-system/templates/KCInvoicePrintTemplate.php
Override path: your-child-theme/kivicare/KCInvoicePrintTemplate.php
Triggered by: REST endpoint GET /wp-json/kivicare/v1/appointments/{id}/print-invoice

Available Variables

VariableTypeDescription
$appointmentarrayidappointmentStartDateappointmentStartTimepaymentModepaymentStatus
$patientarray|nullnameemailphoneaddresscitycountrypostal_codegenderageid
$doctorarray|nullnameemailspecializationsignature
$clinicarray|nullnameaddresscitycountrypostal_codephoneemaillogo
$clinic_logoarrayidurl — the clinic logo attachment
$servicesarrayEach item: namecharges (float)
$tax_itemsarrayResult of apply_filters('kivicare_get_tax_data', $appointment_id) — contains tax_data[] with tax_nametax_amount
$currency_prefixstringCurrency symbol placed before the amount (e.g. $)
$currency_postfixstringCurrency symbol placed after the amount (e.g. USD)
$total_chargesstringPre-formatted subtotal string (number_format)
$sub_totalfloatRaw subtotal float for calculations
$appointmentReportarrayAttached documents — each item: idurlfilename

mPDF Constraints

This template is rendered by mPDF. Keep these in mind when customising:

  • No * { box-sizing: border-box } — unsupported by mPDF.
  • No border-radius on inline/span elements — it is silently ignored.
  • Use <table> for multi-column layouts, not float or flexbox.
  • The <!-- NO_SIMPLE_TABLES --> comment at the top of <body> is required to allow background on <th> elements.
  • The font stack must include DejaVu Sans as the primary font for Unicode/multi-language support.

Override Steps

mkdir -p wp-content/themes/your-child-theme/kivicare
cp wp-content/plugins/kivicare-clinic-management-system/templates/KCInvoicePrintTemplate.php \
   wp-content/themes/your-child-theme/kivicare/KCInvoicePrintTemplate.php

Common Customisations

Change accent colour — find all occurrences of #5F60B9 in the <style> block and replace with your brand colour.

Add a custom logo — replace the logo block:

<img src="<?php echo esc_url($clinic['logo']); ?>" style="height: 60px;">

with a hard-coded path:

<img src="<?php echo esc_url(get_stylesheet_directory_uri()); ?>/assets/my-logo.png" style="height: 60px;">

Change payment status colours:

// Paid  → change #219653
// Unpaid → change #dc2626
$paymentStatusColor = strtolower($paymentStatus) === 'paid' ? '#YOUR_COLOR' : '#YOUR_COLOR';

Template 2 — Encounter Bill / Invoice (KCBillPrintTemplate.php)

Plugin: kivicare-pro
Source: wp-content/plugins/kivicare-pro/templates/KCBillPrintTemplate.php
Override path: your-child-theme/kivicare/KCBillPrintTemplate.php
Triggered by: Bill print action in the Encounters module (KiviCare Pro)

Available Variables

VariableTypeDescription
$billarrayidinvoice_iddatestatusdiscountactual_amount
$patientarrayidnamedobphone
$doctorarrayname
$clinicarraynameaddresscitycountrypostal_codephoneemail
$clinic_logoarrayidurl
$service_itemsarrayEach item: namepricetotal
$tax_itemsarrayEach item: namecharges
$currency_detailarrayprefixpostfix
$payment_methodstringPayment method label (e.g. CashCard)

Helper Functions (defined in template)

money($amount, $currency_detail)  // formats a float with currency prefix/postfix
calc_age($dob)                     // returns age string from date-of-birth

These are defined inside the template file itself. If you override the template, keep or redefine them.

Override Steps

mkdir -p wp-content/themes/your-child-theme/kivicare
cp wp-content/plugins/kivicare-pro/templates/KCBillPrintTemplate.php \
   wp-content/themes/your-child-theme/kivicare/KCBillPrintTemplate.php

mPDF Constraints

  • Multi-column header uses <table> layout (not floats).
  • background on <th> requires the .services class combined with mPDF’s simpleTables=false mode — do not remove the class="services" attribute from service tables.

Template 3 — Patient Encounter (KCEncounterPrintTemplate.php)

Plugin: kivicare-pro
Source: wp-content/plugins/kivicare-pro/templates/KCEncounterPrintTemplate.php
Override path: your-child-theme/kivicare/KCEncounterPrintTemplate.php
Triggered by: Encounter print action in the Encounters module (KiviCare Pro)

Available Variables

VariableTypeDescription
$encounterarraycreated_at
$patientarraynameemailaddresscitypostal_codecountry
$doctorarraynamespecializationsignature
$clinicarraynameaddresscitycountrypostal_codephoneemail
$clinic_logoarrayidurl
$medical_historyarray|nullproblem[]observation[]note[] — each item has a title key
$prescriptionsarrayEach item: namefrequencydurationinstruction
$custom_fieldsarrayEach item: labelvalue

Override Steps

mkdir -p wp-content/themes/your-child-theme/kivicare
cp wp-content/plugins/kivicare-pro/templates/KCEncounterPrintTemplate.php \
   wp-content/themes/your-child-theme/kivicare/KCEncounterPrintTemplate.php

Sections in the Template

SectionConditionalNotes
Header (logo, clinic, doctor, patient info)Always shown
Clinical DetailsOnly if $medical_history not emptyProblems, Observations, Notes
PrescriptionOnly if $prescriptions not empty
Custom FieldsOnly if $custom_fields not empty
Doctor SignatureShows image if $doctor['signature'] set, else blank line

Template 4 — Prescription Print (KCPrescriptionPrintTemplate.php)

Plugin: kivicare-pro
Source: wp-content/plugins/kivicare-pro/templates/KCPrescriptionPrintTemplate.php
Override path: your-child-theme/kivicare/KCPrescriptionPrintTemplate.php
Triggered by: Prescription print action from Encounter detail

Available Variables

VariableTypeDescription
$encounterarrayencounter_date
$patientarraynameemailblood_groupgender
$doctorarraynamespecializationsignature
$clinicarraynameaddresscitycountrypostal_codephoneemail
$clinic_logoarrayidurl
$prescriptionsarrayEach item: namefrequencydurationinstruction
$clinical_detailsarray|nullproblems[]observations[]notes[] — each item has title
$custom_fieldsarrayEach item: labelvalue

Override Steps

mkdir -p wp-content/themes/your-child-theme/kivicare
cp wp-content/plugins/kivicare-pro/templates/KCPrescriptionPrintTemplate.php \
   wp-content/themes/your-child-theme/kivicare/KCPrescriptionPrintTemplate.php

mPDF Constraints

  • The <!-- NO_SIMPLE_TABLES --> comment in <body> is required for <th> background colours to render.
  • Use margin-left (not padding-left) for <ul> indentation inside table cells.
  • border-radius on .logo is silently ignored by mPDF — do not rely on it.

Template 5 — Prescription Email Table (PrescriptionEmailTable.php)

Plugin: kivicare-clinic-management-system
Source: wp-content/plugins/kivicare-clinic-management-system/templates/PrescriptionEmailTable.php
Override path: No built-in child theme override. Use the WordPress filter below.

This template renders the <table> HTML that is embedded inside the prescription notification email. It is loaded directly by PrescriptionController without a theme lookup.

Available Variables

VariableTypeDescription
$prescriptionsarray of objectsEach object has: namefrequencydurationinstruction

How to Override (Filter-Based)

Since there is no child theme path, intercept the email HTML with a WordPress filter in your child theme’s functions.php or a custom plugin:

add_filter('kivicare_prescription_email_html', function( string $html, array $prescriptions ): string {
    ob_start();
    // your custom table markup here, using $prescriptions
    foreach ( $prescriptions as $p ) {
        echo '<tr><td>' . esc_html( $p->name ) . '</td>...</tr>';
    }
    return ob_get_clean();
}, 10, 2);

Note: If the filter kivicare_prescription_email_html does not yet exist in the plugin’s source, the alternative is to copy the template into a mu-plugin or custom plugin and include it via a hooked function that replaces the email body before sending.


Template 6 — Dashboard HTML Shell (html-kc-dashboard.php)

Plugin: kivicare-clinic-management-system
Source: wp-content/plugins/kivicare-clinic-management-system/templates/html-kc-dashboard.php
Override path: No built-in child theme override. Use WordPress hooks below.

This is the full HTML shell (doctype → </html>) for the KiviCare SPA dashboard. The React app mounts into <div id="kc-dashboard">. It is loaded via WordPress’s template_include filter by KCDashboardPermalinkHandler.

What It Controls

FeatureHow it works
Dark / light modedata-bs-theme attribute on <html>, driven by KCOption::get('dark_mode')
RTL / LTRdir attribute on <html>, driven by is_rtl() and KCOption::get('theme_mode')
Custom fontsGoogle Fonts <link> injected when title/body font differs from Inter
Brand coloursCSS custom properties (--bs-primary--bs-secondary, etc.) output from KCOption::get('generated_colors')
React mount point<div id="kc-dashboard"></div>

Available Variables

VariableTypeDescription
$dashboard_configarrayTheme, layout, sidebar, RTL, dark mode, user role — passed to kivicare_dashboard_config filter
$dark_modeboolWhether dark mode is active for this user
$titleFontstringTitle font name from clinic settings
$bodyFontstringBody font name from clinic settings

Extension Hooks

// Add content to <head> (scripts, meta tags, custom CSS)
add_action('kivicare_dashboard_head', function( array $config ) {
    echo '<link rel="stylesheet" href="...">';
}, 10, 1);

// Add content before </body> (tracking scripts, overlays)
add_action('kivicare_dashboard_footer', function( array $config ) {
    echo '<script>...</script>';
}, 10, 1);

// Runs after wp_footer(), last hook before </body>
add_action('kivicare_dashboard_end', function() {
    // cleanup or injections
});

// Modify dashboard config before it is applied
add_filter('kivicare_dashboard_config', function( array $config ): array {
    $config['theme'] = 'dark';
    return $config;
});

// Modify the page title
add_filter('kivicare_dashboard_title', function( string $title, string $role ): string {
    return 'My Clinic — ' . $title;
}, 10, 2);

Language / Translation

All string labels in every template use __() or esc_html__() with the appropriate text domain:

  • Core templates → text domain: kivicare-clinic-management-system
  • Pro templates → text domain: kivicare-pro

To change the language of printed documents:

MethodScope
Settings → General → Site LanguageAll users site-wide
User Profile → LanguagePer-user (affects that user’s downloaded PDFs)
Edit strings directly in your overridden templatePer-template, locale-independent

Tips

  • Test with a real PDF download after every change — mPDF silently ignores unsupported CSS rather than erroring.
  • The PDF font is DejaVu Sans. For languages that require complex script shaping (e.g. Arabic, Gujarati, Hindi), ensure autoLangToFont and autoScriptToLang remain enabled in the PDF config (they are on by default in the invoice controller).
  • Keep the <!-- NO_SIMPLE_TABLES --> HTML comment in templates that use background colours on <th> — removing it will cause header backgrounds to disappear.
  • All override templates support the standard esc_html()esc_url(), and esc_attr() escaping functions — use them on every output to stay XSS-safe.
Suggestions & Improvements

Suggestions & Improvements

Your email address will not be published