Skip to content

Instantly share code, notes, and snippets.

@psaikali
Last active April 2, 2017 13:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save psaikali/d11c7680adfc11c7198e17d4df161d65 to your computer and use it in GitHub Desktop.
Save psaikali/d11c7680adfc11c7198e17d4df161d65 to your computer and use it in GitHub Desktop.
Utiliser des jolis templates d'e-mails dans WordPress et remplacer des mots par des variables
<?php
/*
* Usage de la fonction msk_send_mail
*/
$destinataire = 'pierre@mosaika.fr';
$data = array(
'prenom' => 'Bruce',
'nom' => 'Willis',
'email' => 'bruce.willis@laposte.net',
'url' => 'https://mosaika.fr'
);
$retour = msk_send_mail('template_when_this_happens', $destinataire, $data);
if (isset($retour['error']) && $retour['error'] == 0) {
// L'e-mail a été envoyé
} else {
// Erreur, vérifiez $retour['message'] pour en savoir plus
}
<?php
/**
* Envoyer un e-mail : on se base sur un template et on remplace des "placeholders" par des variables dynamiques
*/
function msk_send_mail($template = '', $to = '', $data = array()) {
// Définissez ici les différents modèles d'e-mail à suivre
$available_templates = array(
// Le template d'un premier e-mail
'template_when_this_happens' => array(
'subject' => __('Le sujet de l\'email s\'affiche ici', 'mosaika'),
'content' => __('<p>Bonjour {{ prenom }} {{ nom }} !</p><p>Une nouvelle inscription sur notre site a été faite avec l\'e-mail {{ email }}. Pour vous connecter, <a href="{{ url }}">rendez-vous sur cette page</a>.</p>', 'mosaika')
),
// Le template d'un autre e-mail
'another_template_when_that_happens' => array(
'subject' => __('Le sujet de l\'email s\'affiche ici', 'mosaika'),
'content' => __('<p>Bonjour {{ prenom }} {{ nom }} !</p><p>Une nouvelle inscription sur notre site a été faite avec l\'e-mail {{ email }}. Pour vous connecter, <a href="{{ url }}">rendez-vous sur cette page</a>.</p>', 'mosaika')
),
);
if ($to == '') {
$error = 'Erreur d\'envoi d\'un e-mail : destinataire vide.';
} else if ($template == '') {
$error = 'Erreur d\'envoi d\'un e-mail : template vide.';
} else if (!array_key_exists($template, $available_templates)) {
$error = 'Erreur d\'envoi d\'un e-mail : template inexistant.';
} else {
if (!is_array($to)) $to = array($to);
// Si le site est en développement, on envoie l'e-mail à l'administrateur du site
if (WP_DEBUG) $to = array(get_option('admin_email'));
// On récupère le tableau correspondant au template à analyser/transformer
$template_data = $available_templates[$template];
$mail_subject_template = $template_data['subject'];
$mail_content_template = $template_data['content'];
// On transforme les {{ placeholders }} par les variables fournies dans $data (pour le sujet et le corps du mail)
// Par exemple, {{ email }} est remplacé par la valeur de $data['email'], {{ prenom }} par la valeur de $data['prenom']
$mail_subject = msk_transform_vars_to_value($mail_subject_template, $data);
$mail_content = msk_transform_vars_to_value($mail_content_template, $data);
// On intègre le corps/contenu de notre e-mail à la place de {{ body }} dans le fichier /emails/base.tpl
$mail_html = msk_parse_email_body_content_in_template(array('body' => wpautop($mail_content)));
// On s'assure que l'e-mail envoyé est au format HTML
$mail_headers = array('Content-Type: text/html; charset=UTF-8');
// On envoie l'email
if (!wp_mail($to, $mail_subject, $mail_html, $mail_headers)) {
$error = 'Erreur durant l\'envoi de l\'e-mail.';
}
if ($error) {
return array('error' => 1, 'message' => $error);
} else {
return array('error' => 0);
}
}
}
/**
* Transforme {{ variable }} en sa valeur correspondante dans le tableau fourni
*/
function msk_transform_vars_to_value($template, $vars) {
$output = $template;
foreach ($vars as $key => $value) {
$tag_to_replace = "{{ $key }}";
$output = str_replace($tag_to_replace, $value, $output);
}
return $output;
}
/**
* Permet de récupérer tout le contenu HTML de l'e-mail à envoyer, avec tous les {{ placeholders }} remplacés par les valeurs fournies
*/
function msk_parse_email_body_content_in_template($data) {
require_once(get_stylesheet_directory() . '/emails/emailTemplate.php');
$defaults = array(
'preheader' => 'Cet e-mail vous est envoyé par XYZ. <a href="http://mosaika.fr">Cliquez-ici</a> pour visiter notre site.',
'logo' => get_stylesheet_directory_uri() . '/emails/logo.png',
'body' => '',
'footer' => 'Copyright 2017 XYZ.',
);
$tags = wp_parse_args($data, $defaults);
$email_content = new MailTemplate(get_stylesheet_directory() . '/emails/base.tpl');
foreach ($tags as $tag_name => $tag_value) {
$email_content->set($tag_name, $tag_value);
}
return $email_content->output();
}
<?php
/**
* Simple template engine class (use [@tag] tags in your templates).
* (merci à http://www.broculos.net/2008/03/how-to-make-simple-html-template-engine.html#.WODf9N-YFhE pour le code)
*
* @link http://www.broculos.net/ Broculos.net Programming Tutorials
* @author Nuno Freitas <nunofreitas@gmail.com>
* @version 1.0
*/
class MailTemplate {
/**
* The filename of the template to load.
*
* @access protected
* @var string
*/
protected $file;
/**
* An array of values for replacing each tag on the template (the key for each value is its corresponding tag).
*
* @access protected
* @var array
*/
protected $values = array();
/**
* Creates a new Template object and sets its associated file.
*
* @param string $file the filename of the template to load
*/
public function __construct($file) {
$this->file = $file;
}
/**
* Sets a value for replacing a specific tag.
*
* @param string $key the name of the tag to replace
* @param string $value the value to replace
*/
public function set($key, $value) {
$this->values[$key] = $value;
}
/**
* Outputs the content of the template, replacing the keys for its respective values.
*
* @return string
*/
public function output() {
/**
* Tries to verify if the file exists.
* If it doesn't return with an error message.
* Anything else loads the file contents and loops through the array replacing every key for its value.
*/
if (!file_exists($this->file)) {
return "Error loading template file ($this->file).<br />";
}
$output = file_get_contents($this->file);
foreach ($this->values as $key => $value) {
$tagToReplace = "{{ $key }}";
$output = str_replace($tagToReplace, $value, $output);
}
return $output;
}
/**
* Merges the content from an array of templates and separates it with $separator.
*
* @param array $templates an array of Template objects to merge
* @param string $separator the string that is used between each Template object
* @return string
*/
static public function merge($templates, $separator = "\n") {
/**
* Loops through the array concatenating the outputs from each template, separating with $separator.
* If a type different from Template is found we provide an error message.
*/
$output = "";
foreach ($templates as $template) {
$content = (get_class($template) !== "Template")
? "Error, incorrect type - expected Template."
: $template->output();
$output .= $content . $separator;
}
return $output;
}
}
?>
<!doctype html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Mon super e-mail grâce à www.mosaika.fr</title>
<style>
/* -------------------------------------
GLOBAL RESETS
------------------------------------- */
img {
border: none;
-ms-interpolation-mode: bicubic;
max-width: 100%; }
body {
background-color: #f6f6f6;
font-family: "Helvetica Neue", "Helvetica", Tahoma, sans-serif;
-webkit-font-smoothing: antialiased;
font-size: 14px;
line-height: 1.4;
margin: 0;
padding: 0;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%; }
table {
border-collapse: separate;
mso-table-lspace: 0pt;
mso-table-rspace: 0pt;
width: 100%; }
table td {
font-family: "Helvetica Neue", "Helvetica", Tahoma, sans-serif;
vertical-align: middle; }
/* -------------------------------------
BODY & CONTAINER
------------------------------------- */
.body {
background-color: #f6f6f6;
width: 100%; }
/* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink down on a phone or something */
.container {
display: block;
Margin: 0 auto !important;
/* makes it centered */
max-width: 580px;
padding: 10px;
width: auto !important;
width: 580px; }
/* This should also be a block element, so that it will fill 100% of the .container */
.content {
box-sizing: border-box;
display: block;
Margin: 0 auto;
max-width: 580px;
padding: 10px; }
/* -------------------------------------
HEADER, FOOTER, MAIN
------------------------------------- */
.main {
background: #fff;
border-radius: 3px;
width: 100%; }
.wrapper {
box-sizing: border-box;
padding: 20px; }
.footer {
clear: both;
padding-top: 10px;
text-align: center;
width: 100%; }
.footer td,
.footer p,
.footer span,
.footer a {
color: #999999;
font-size: 12px;
text-align: center; }
/* -------------------------------------
TYPOGRAPHY
------------------------------------- */
h1,
h2,
h3,
h4 {
font-weight:bold;
color:#00578f;
margin-top:20px;
margin-bottom:10px;
font-family: "Helvetica Neue", "Helvetica", Tahoma, sans-serif;
line-height: 1.4;
margin: 0;
}
h1 {
font-size: 32px;
}
h2 {
font-size: 28px;
}
h3 {
font-size: 24px;
}
h4 {
font-size: 20px;
}
h5 {
font-size: 17px;
}
blockquote {
border-left:3px solid #DADADA;
margin-left: 20px;
padding-left: 20px;
font-style: italic;
}
p,
ul,
ol {
font-family: "Helvetica Neue", "Helvetica", Tahoma, sans-serif;
font-size: 14px;
font-weight: normal;
margin: 0;
Margin-bottom: 15px; }
p li,
ul li,
ol li {
list-style-position: inside;
margin-left: 5px; }
a {
color: #3498db;
text-decoration: underline; }
/* -------------------------------------
BUTTONS
------------------------------------- */
.btn {
box-sizing: border-box;
width: 100%; }
.btn > tbody > tr > td {
padding-bottom: 15px; }
.btn table {
width: auto; }
.btn table td {
background-color: #ffffff;
border-radius: 5px;
text-align: center; }
.btn a {
background-color: #ffffff;
border: solid 1px #3498db;
border-radius: 5px;
box-sizing: border-box;
color: #3498db;
cursor: pointer;
display: inline-block;
font-size: 14px;
font-weight: bold;
margin: 0;
padding: 12px 25px;
text-decoration: none;
text-transform: capitalize; }
.btn-primary table td {
background-color: #3498db; }
.btn-primary a {
background-color: #3498db;
border-color: #3498db;
color: #ffffff; }
/* -------------------------------------
OTHER STYLES THAT MIGHT BE USEFUL
------------------------------------- */
.last {
margin-bottom: 0; }
.first {
margin-top: 0; }
.align-center {
text-align: center; }
.align-right {
text-align: right; }
.align-left {
text-align: left; }
.clear {
clear: both; }
.mt0 {
margin-top: 0; }
.mb0 {
margin-bottom: 0; }
.preheader {
color: transparent;
display: none;
height: 0;
max-height: 0;
max-width: 0;
opacity: 0;
overflow: hidden;
mso-hide: all;
visibility: hidden;
width: 0; }
.powered-by a {
text-decoration: none; }
hr {
border: 0;
border-bottom: 1px solid #e6e6e6;
Margin: 16px 0; }
.logo {
text-align: center;
}
.logo a {
display:block;
text-align: center;
}
.logo a img {
margin:0 auto;
}
.logo hr {
border: 0;
border-bottom: 2px solid #e6e6e6;
margin: 12px 0 0; }
/* -------------------------------------
RESPONSIVE AND MOBILE FRIENDLY STYLES
------------------------------------- */
@media only screen and (max-width: 620px) {
table[class=body] h1 {
font-size: 28px !important;
margin-bottom: 10px !important; }
table[class=body] p,
table[class=body] ul,
table[class=body] ol,
table[class=body] td,
table[class=body] span,
table[class=body] a {
font-size: 16px !important; }
table[class=body] .wrapper,
table[class=body] .article {
padding: 10px !important; }
table[class=body] .content {
padding: 0 !important; }
table[class=body] .container {
padding: 0 !important;
width: 100% !important; }
table[class=body] .main {
border-left-width: 0 !important;
border-radius: 0 !important;
border-right-width: 0 !important; }
table[class=body] .btn table {
width: 100% !important; }
table[class=body] .btn a {
width: 100% !important; }
table[class=body] .img-responsive {
height: auto !important;
max-width: 100% !important;
width: auto !important; }}
/* -------------------------------------
PRESERVE THESE STYLES IN THE HEAD
------------------------------------- */
@media all {
.ExternalClass {
width: 100%; }
.ExternalClass,
.ExternalClass p,
.ExternalClass span,
.ExternalClass font,
.ExternalClass td,
.ExternalClass div {
line-height: 100%; }
.apple-link a {
color: inherit !important;
font-family: inherit !important;
font-size: inherit !important;
font-weight: inherit !important;
line-height: inherit !important;
text-decoration: none !important; }
.btn-primary table td:hover {
background-color: #34495e !important; }
.btn-primary a:hover {
background-color: #34495e !important;
border-color: #34495e !important; } }
</style>
</head>
<body class="">
<table border="0" cellpadding="0" cellspacing="0" class="body">
<tr>
<td>&nbsp;</td>
<td class="container">
<div class="content">
<!-- START CENTERED WHITE CONTAINER -->
<span class="preheader">{{ preheader }}</span>
<table class="main">
<tr>
<td class="wrapper logo">
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<a href="http://www.mosaika.fr/"><img src="{{ logo }}" width="221" height="86" /></a>
<hr>
</td>
</tr>
</table>
</td>
</tr>
<!-- START MAIN CONTENT AREA -->
<tr>
<td class="wrapper">
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
{{ body }}
</td>
</tr>
</table>
</td>
</tr>
<!-- END MAIN CONTENT AREA -->
</table>
<!-- START FOOTER -->
<div class="footer">
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td class="content-block">
<span class="apple-link">{{ footer }}</span>
</td>
</tr>
</table>
</div>
</div>
</td>
<td>&nbsp;</td>
</tr>
</table>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment