Process greeting templates with Smarty
authorOlaf Buddenhagen <antrik@digitalcourage.de>
Mon, 15 Jul 2013 06:12:39 +0000 (08:12 +0200)
committerOlaf Buddenhagen <antrik@digitalcourage.de>
Wed, 9 Oct 2013 10:06:53 +0000 (12:06 +0200)
commit73d64eb695adbf17d25e1714226e519b4a6e155b
treebeaebe7a573d7712624de771111ca77bc16d4a15
parent296342b115f405588fe5aa0b712f84793c6bca43
Process greeting templates with Smarty

When expanding `email_greeting`, `postal_greeting`, and `addressee`
templates, after substituting the CiviCRM tokens, pass the result
through Smarty.

This way it becomes possible to include conditionals (or other types of
fancy processing) in greeting templates. Example:

  {capture assign=style}{contact.communication_style}{/capture}
  {capture assign=prefix}{contact.individual_prefix}{/capture}
  {if $style=="Familiar"}
    {if $prefix=="Frau"}
      Liebe
    {elseif $prefix=="Herr"}
      Lieber
    {else}
      Liebe/r
    {/if}
    {contact.first_name}
  {else}
    {if $prefix=="Frau"}
      Liebe Frau
    {elseif $prefix=="Herr"}
      Lieber Herr
    {else}
      Liebe/r Herr oder Frau
    {/if}
    {contact.formal_title} {contact.last_name}
  {/if}

The major limitation of this approach is that the `label` field -- where
the actual greeting templates are stored -- is limited to 255
characters. (So the above example wouldn't actually work without some
trickery to make it shorter...) Not sure how to address this problem.

We are wondering whether we should hide this feature behind a config
option, like it is done for Mailings? I'm not sure this is really
necessary here, as the Smarty processing shouldn't be in anyone's way
when unused. The only possible downside is that templates with syntax
errors might produce somewhat obscure warnings or errors in some cases.
However, the greeting templates are generally only set up during the
implementation phase, and never touched by mortal users -- just like
system workflow message templates, which use Smarty unconditionally as
well. Also, it feels wrong to hide such useful functionality behind some
obscure option...

To allow for proper Smarty escaping, this patch needs to introduce some
small changes to the way contact tokens are processed in the greetings.
These shouldn't affect other callers.

To avoid code duplication, a new function is introduced for the template
processing (tokens+Smarty), adding another layer of indirection. This
could be avoided, if replaceGreetingTokens() wasn't used in other
contexts too. (Which I believe is a misunderstanding: I'm pretty sure
the function was only meant for *generating* the greeting texts, by
replacing tokens in the greeting templates when saving a contact record;
and not for replacing greeting tokens in message templates -- the latter
should be handled just fine along with the other contact tokens...)
CRM/Contact/BAO/Contact.php
CRM/Contact/BAO/Contact/Utils.php
CRM/Utils/Token.php
bin/deprecated/UpdateGreeting.php