Skip to content



This hook is called after getting the content of the mail and before tokenizing it.




  • $content - fields that include the content of the mail


$content - fields include: - html - text - subject - workflow_name (from 5.35, replaces valueName) - groupName (deprecated, no replacement) - valueName (deprecated, use workflow_name) - messageTemplateID (use when the template was selected by id not workflow_name) - mailingID - campaign_id - template_type

See discussion at about deprecation of valueName and groupName and move to using the field civicrm_message_template.workflow_name.

Note that this hook is fired when:

  • creating mailings through the traditional BAO mailer (standard CiviMail)
  • creating mailings through FlexMailer (used by Mosaico)
  • sending emails using message templates, in CRM_Core_BAO_MessageTemplate

In the latter case there is inherently no mailingID or template_type, so these will not be supplied. Similarly in the 2 former cases the messageTemplateID is not supplied.


    * Implement hook_civicrm_alterMailContent
    * Replace invoice template with custom content from file
  function mail_civicrm_alterMailContent(&$content) {
    if ($content['workflow_name'] ?? NULL === 'contribution_invoice_receipt') {
      $path = Civi::resources()->getPath('org.myorg.invoice');
      $html = file_get_contents($path.'/msg/contribution_invoice_receipt.html.tpl');
      $content['html'] = $html;