====== Better Email Notifications with HTML formatting ====== This hack was in part inspired by the beautiful page change notifications sent out by other wiki software such as PBWiki, which uses HTML formatting instead of plain-text, and in part inspired by the existing diff rendering system in DokuWiki. I figured if DokuWiki is already capable of generating nicely formatted diff of page changes, I could tap into the system to send out HTML-formatted page notifications. ===== UPDATEs: ===== * Instructions updated for DokuWiki 2008-04-11 RC2. * edited hack for notification on new pages * tested and working on DokuWiki 2008-05-05 * tested and working on DokuWiki 2009-12-25c * tested and working on DokuWiki 2011-05-25a ===== Screenshots of before and after ===== {{http://artichoked.net/misc/doku-sample-old.png?300 }} {{http://artichoked.net/misc/doku-sample-email.png?300 }} {{http://oct22.imgshare.us/zl0.png?300}} //please host this last image on your own website... i can't guarantee the [[http://oct22.imgshare.us/zl0.png|imgshare link]] will last.// ===== What you need ====== * Plain text editor((I used TextWrangler on the Mac. You should probably use Wordpad if you're on Windows because Notepad doesn't understand the Unix style line endings.)) * [[http://www.splitbrain.org/_media/projects/dokuwiki/dokuwiki-2007-06-26.tgz?id=projects%3Adokuwiki&cache=cache|DokuWiki 2007-06-26]]((Line numbers are given based on this version.)), [[http://www.splitbrain.org/_media/projects/dokuwiki/dokuwiki-2008-05-05.tgz|2008-05-05]] or [[http://www.splitbrain.org/_media/projects/dokuwiki/dokuwiki-2009-12-25c.tgz|2009-12-25c]]((tested and working with DokuWiki 2008-05-05 & 2009-12-25c, but line numbers don't match the hack explanation, feel free to correct.)) * DokuWiki files you'll be editing: * inc/mail.php * inc/common.php ===== Applying the hack ===== ==== inc/mail.php ==== First, we need to create a new function that can handle our HTML e-mails. We'll do so by creating one based on mail_send() in mail.php. Open up the file and locate the mail_send() function function mail_send($to, $subject, $body, $from='', $cc='', $bcc='', $headers=null, $params=null){ at line 36((Line 67 of Rincewind)) of an unmodified mail.php. Insert the following code just **above** the mail_send() function. /*********************************** * HTML Mail functions * * Sends HTML-formatted mail * By Lin Junjie (mail [dot] junjie [at] gmail [dot] com) * ***********************************/ function mail_send_html($to, $subject, $body, $bodyhtml, $from='', $cc='', $bcc='', $headers=null, $params=null){ if(defined('MAILHEADER_ASCIIONLY')){ $subject = utf8_deaccent($subject); $subject = utf8_strip($subject); } if(!utf8_isASCII($subject)) { $subject = '=?UTF-8?Q?'.mail_quotedprintable_encode($subject,0).'?='; // Spaces must be encoded according to rfc2047. Use the "_" shorthand $subject = preg_replace('/ /', '_', $subject); } $header = ''; $usenames = (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') ? false : true; $random_hash = md5(date('r', time())); // added $to = mail_encode_address($to,'',$usenames); $header .= mail_encode_address($from,'From'); $header .= mail_encode_address($cc,'Cc'); $header .= mail_encode_address($bcc,'Bcc'); $header .= 'MIME-Version: 1.0'.MAILHEADER_EOL; $header .= "Content-Type: multipart/alternative; boundary=PHP-alt-".$random_hash.MAILHEADER_EOL; $header .= $headers; $header = trim($header); $body = mail_quotedprintable_encode($body); $bodyhtml = mail_quotedprintable_encode($bodyhtml); $message = "--PHP-alt-".$random_hash."\r\n". "Content-Type: text/plain; charset=UTF-8"."\r\n". "Content-Transfer-Encoding: quoted-printable"."\r\n\r\n". $body."\r\n\r\n". "--PHP-alt-".$random_hash."\r\n". "Content-Type: text/html; charset=UTF-8"."\r\n". "Content-Transfer-Encoding: quoted-printable"."\r\n\r\n". $bodyhtml."\r\n". "--PHP-alt-".$random_hash."--"; if($params == null){ return @mail($to,$subject,$message,$header); }else{ return @mail($to,$subject,$message,$header,$params); } } The function has the added advantage of sending along the standard plain-text version for mail clients that cannot display HTML formatting. That's all for mail.php. ==== inc/common.php ==== There are three parts of hack to apply to common.php. **Part 1** First, we need to intercept the mailing action and generate a HTML-formatted version of the notification. Locate the following code $diff = $dformat->format($df); in the notify() function at line 877((1148 Rincewind)) of an unmodified common.php and insert the following code right **after** it: /*********************************** * Generate HTML Notification Hack (Part 1) * * inc/common.php * By Lin Junjie (mail [dot] junjie [at] gmail [dot] com) * ***********************************/ $df = new Diff(explode("\n",htmlspecialchars(rawWiki($id,$rev))), explode("\n",htmlspecialchars(rawWiki($id,'')))); $left = ''. $id.' '.strftime($conf['dformat']).''; $right = ''. $id.' '.strftime($conf['dformat'],@filemtime(wikiFN($id))).' ('. $lang['current'] . ')'; $tdf = new TableDiffFormatter(); $diffHTML = "\n\n

".$id. " was just edited

\n

by ". $_SERVER['REMOTE_USER']." on ".strftime($conf['dformat'])."


\n"."\n\n\n\n".$tdf->format($df). "
\n". $left."\n".$right."
\n"."
\n

---
\nThis mail was ". "automatically generated by DokuWiki at
\n".DOKU_URL."

\n". "\n"; $diffHTML = str_replace('class="diff-blockheader"','style="font-weight: bold; font-family: courier new;"',$diffHTML); $diffHTML = str_replace('class="diff-addedline"','style="background-color: #ddffdd; font-family: courier new;"',$diffHTML); $diffHTML = str_replace('class="diff-deletedline"','style="background-color: #ffffbb; font-family: courier new;"',$diffHTML); $diffHTML = str_replace('class="diff-context"','style="background-color: #f5f5f5; font-family: courier new;"',$diffHTML); $diffHTML = str_replace('class="diffchange"','style="color: red;"',$diffHTML); $diffHTML = str_replace('','',$diffHTML); $diffHTML = str_replace('','',$diffHTML); $diffHTML = str_replace('','',$diffHTML); /*********************************** * End Generate HTML Notification Hack (Part 1) ***********************************/
**Part 2** Then intercept the mailing action and generate a HTML-formatted version of the notification on new page creation. Locate the following code $diff = rawWiki($id); in the notify() function of inc/common.php and insert the following code right **after** it: /*********************************** * Generate HTML Notification Hack (Part 2) * * inc/common.php * By Berteh (berteh [at] hotmail [dot] com) * ***********************************/ $diffHTML = "\n\n

".$id. " was just added

\n

by ". $_SERVER['REMOTE_USER']." on ".strftime($conf['dformat'])."


\n".p_wiki_xhtml($id). "\n"."
\n

---
\nThis mail was ". "automatically generated by DokuWiki at
\n".DOKU_URL."

\n". "\n"; /*********************************** * End Generate HTML Notification Hack (Part 2) ***********************************/
**Part 3** Next, we will need to call our mail_send_html() function to send out the HTML-formatted email that we have generated. Locate the following code mail_send($to,$subject,$text,$conf['mailfrom'],'',$bcc); right before the notify() function ends. **REPLACE** this line of code with the following code: /*********************************** * Generate HTML Notification Hack (Part 3) * * inc/common.php * By Lin Junjie (mail [dot] junjie [at] gmail [dot] com) * ***********************************/ if ($diffHTML) { mail_send_html($to,$subject,$text,$diffHTML,$conf['mailfrom'],'',$bcc); }else { mail_send($to,$subject,$text,$conf['mailfrom'],'',$bcc); } /*********************************** * End Generate HTML Notification Hack (Part 3) ***********************************/ Note that part 3 of the hack has the added functionality of changing the sender of the mail to the name of the user that made the change.((Adapted from http://www.dokuwiki.org/wiki:discussion:better_notification.)) Do replace the two instances of "INSERT-YOUR-SERVER-HERE.com" with your own server. If you want to **show the mail of the user** that made the change as mail sender rather than a no-reply address use $sendermail = $INFO['userinfo']['name']. ' <'.$INFO['userinfo']['mail'].'>'; if ($diffHTML) { mail_send_html($to,$subject,$text,$diffHTML,$sendermail,'',$bcc); }else { mail_send($to,$subject,$text,$sendermail,'',$bcc); } ==== That's all folks ==== That's it! We're done! Leave a message here or contact me at mail [dot] junjie [at] gmail [dot] com. If you have any way of integrating this into a plugin, please do so and let us know here! ===== history ===== * 2008.10.23: update to handle notifications on new pages ---[[berteh@hotmail.com|berteh]] * 2008.10.23: update to get absolute links in notifications titles, using ''wl( .. ,.., true);'' function ---[[berteh@hotmail.com|berteh]] ===== Questions and problems ===== * The HTML version of the e-mail works fine in my web mail, but MS Outlook shows the plain text version. * I tried this hack on version 2011-05-25a, it works, but does not support extended notification (digest and so on), one should look at extend inc/subscription.php