Partially convert new follower notification to new email API
authorTim Düsterhus <duesterhus@woltlab.com>
Thu, 16 Jun 2016 15:23:55 +0000 (17:23 +0200)
committerTim Düsterhus <duesterhus@woltlab.com>
Fri, 29 Jul 2016 14:25:53 +0000 (16:25 +0200)
com.woltlab.wcf/templates/email_html.tpl
com.woltlab.wcf/templates/email_notification.tpl
com.woltlab.wcf/templates/email_notification_userFollowFollowing.tpl [new file with mode: 0644]
com.woltlab.wcf/templates/email_plaintext.tpl
com.woltlab.wcf/templates/email_userInformationHeadline.tpl [new file with mode: 0644]
wcfsetup/install/files/lib/system/user/notification/UserNotificationHandler.class.php
wcfsetup/install/files/lib/system/user/notification/event/IUserNotificationEvent.class.php
wcfsetup/install/files/lib/system/user/notification/event/UserFollowFollowingUserNotificationEvent.class.php
wcfsetup/install/lang/de.xml
wcfsetup/install/lang/en.xml

index bcfdf3da55676621946c8847cca77641642c4ed4..030e52da6aec9883a35afa2bb531008c12437452 100644 (file)
                        text-decoration: none;
                }
                
+               td {
+                       vertical-align: top;
+               }
+               
                {* see email_paddingHelper.tpl *}
                table.paddingHelper.block {
                        width: 100%;
                td.button a {
                        color: {$style->getVariable('wcfButtonPrimaryText', true)};
                }
+               
+               .box128 {
+                       border-top: 1px solid {$style->getVariable('wcfContentBorder', true)};
+                       border-bottom: 1px solid {$style->getVariable('wcfContentBorder', true)};
+                       padding: 20px;
+               }
+               
+               .containerHeadline h3 {
+                       margin: 0;
+                       padding: 0;
+               }
                </style>
        </head>
        <body>
index 0595d9ab170f8b5026f5b2cd93c498d6cc1924a3..5fb06f5b02db7435108d3c91ef50781d9af38835 100644 (file)
@@ -2,17 +2,21 @@
 {capture assign='content'}
 {lang}wcf.user.notification.mail.plaintext.intro{/lang}
 
-{@$notificationContent}
+{if $notificationContent|is_array}{include file=$notificationContent[template] application=$notificationContent[application]}{*
+*}{else}{@$notificationContent}{/if}
 
 {lang}wcf.user.notification.mail.plaintext.outro{/lang}
 {/capture}
 {include file='email_plaintext'}
 {else}
        {capture assign='content'}
-       <h1>{lang}wcf.user.notification.mail.html.headline{/lang}</h1>
        {lang}wcf.user.notification.mail.html.intro{/lang}
 
-       {@$notificationContent}
+       {if $notificationContent|is_array}
+               {include file=$notificationContent[template] application=$notificationContent[application]}
+       {else}
+               {@$notificationContent}
+       {/if}
 
        {lang}wcf.user.notification.mail.html.outro{/lang}
        {/capture}
diff --git a/com.woltlab.wcf/templates/email_notification_userFollowFollowing.tpl b/com.woltlab.wcf/templates/email_notification_userFollowFollowing.tpl
new file mode 100644 (file)
index 0000000..7618d20
--- /dev/null
@@ -0,0 +1,18 @@
+{if $mimeType === 'text/plain'}
+{lang}wcf.user.notification.follow.mail.plaintext{/lang}
+{else}
+       {assign var='user' value=$event->getAuthor()}
+       {capture assign='userContent'}
+       <table cellpadding="0" cellspacing="0" border="0">
+               <tr>
+                       <td><a href="{link controller='User' object=$user}{/link}" title="{$user->username}">{@$user->getAvatar()->getImageTag(128)}</a></td>
+                       <td>
+                               {include file='email_userInformationHeadline'}
+                       </td>
+               </tr>
+       </table>
+       {/capture}
+       {include file='email_paddingHelper' block=true class='box128' content=$userContent sandbox=true}
+       <br style="clear:both">
+       {lang}wcf.user.notification.follow.mail.html{/lang}
+{/if}
index 50bdae538a0bf0330a9c4a2b9457e86985f36d11..f3ce6aa970f4f6290db0f69f7aec95f6ee65dd4e 100644 (file)
@@ -1,8 +1,8 @@
-{if $beforeContent|isset}{@$beforeContent}{/if}
+{if $beforeContent|isset}{@$beforeContent}
 
-{@$content}
+{/if}{@$content}{if $afterContent|isset}
 
-{if $afterContent|isset}{@$afterContent}{/if}
+{@$afterContent}{/if}
 {hascontent} {* this line ends with a space *}
 
 -- {* this line ends with a space *}
diff --git a/com.woltlab.wcf/templates/email_userInformationHeadline.tpl b/com.woltlab.wcf/templates/email_userInformationHeadline.tpl
new file mode 100644 (file)
index 0000000..1296ecf
--- /dev/null
@@ -0,0 +1,11 @@
+<div class="containerHeadline">
+       <h3><a href="{link controller='User' object=$user}{/link}" class="username">{$user->username}</a></h3>
+</div>
+<div>
+       {if $__wcf->getSession()->getPermission('user.profile.canViewUserProfile') && $user->isAccessible('canViewProfile')}
+               {if $user->isVisibleOption('gender') && $user->gender}{lang}wcf.user.gender.{if $user->gender == 1}male{else}female{/if}{/lang}, {/if}
+               {if $user->isVisibleOption('birthday') && $user->getAge()}{@$user->getAge()}, {/if}
+               {if $user->isVisibleOption('location') && $user->location}{lang}wcf.user.membersList.location{/lang}, {/if}
+       {/if}
+       {lang}wcf.user.membersList.registrationDate{/lang}
+</div>
index cc8e876d3baeb92b9bd4ff838248fbc40fd29b88..4682001aaab8279cb4af3124939b5d52886a5284 100644 (file)
@@ -14,7 +14,7 @@ use wcf\system\cache\runtime\UserProfileRuntimeCache;
 use wcf\system\database\util\PreparedStatementConditionBuilder;
 use wcf\system\event\EventHandler;
 use wcf\system\exception\SystemException;
-use wcf\system\email\mime\AbstractMimePart;
+use wcf\system\email\mime\MimePartFacade;
 use wcf\system\email\mime\RecipientAwareTextMimePart;
 use wcf\system\email\Email;
 use wcf\system\email\UserMailbox;
@@ -664,15 +664,28 @@ class UserNotificationHandler extends SingletonFactory {
                        'title' => $event->getEmailTitle()
                ]));
                $email->addRecipient(new UserMailbox($user));
+               // TODO: MessageID, References, In-Reply-To
                
                $message = $event->getEmailMessage('instant');
-               if ($message instanceof AbstractMimePart) {
-                       $email->setBody($message);
+               if (is_array($message)) {
+                       $variables = [
+                               'notificationContent' => $message,
+                               'event' => $event,
+                               'notificationType' => 'instant'
+                       ];
+                       if (isset($message['variables'])) {
+                               $variables['variables'] = $message['variables'];
+                       }
+                       
+                       $html = new RecipientAwareTextMimePart('text/html', 'email_notification', 'wcf', $variables);
+                       $plainText = new RecipientAwareTextMimePart('text/plain', 'email_notification', 'wcf', $variables);
+                       $email->setBody(new MimePartFacade([$html, $plainText]));
                }
                else {
                        $email->setBody(new RecipientAwareTextMimePart('text/plain', 'email_notification', 'wcf', [
                                'notificationContent' => $message,
-                               'event' => $event
+                               'event' => $event,
+                               'notificationType' => 'instant'
                        ]));
                }
                
index 821f53988a2438946e2a14ca8e62519c9635bf72..3b7c975c0984f81efeda6a3ed8536dc4816d6db2 100644 (file)
@@ -49,8 +49,18 @@ interface IUserNotificationEvent extends IDatabaseObjectProcessor {
        /**
         * Returns the message for this notification event.
         * 
+        * If $notificationType is 'instant' this method should either:
+        * - Return a string to be inserted into a text/plain email (deprecated)
+        * - Return a ['template' => ..., 'application' => ..., 'variables' => ...] array
+        *   to be included into the summary email.
+        * 
+        * If $notificationType is 'daily' this method should either:
+        * - Return a string to be inserted into the summary email (deprecated)
+        * - Return a ['template' => ..., 'application' => ..., 'variables' => ...] array
+        *   to be included into the summary email.
+        * 
         * @param       string          $notificationType
-        * @return      string
+        * @return      mixed
         */
        public function getEmailMessage($notificationType = 'instant');
        
index b04f468fce292f5e377e7d30904a762100504eb8..afd6ccd6426ed0e59b3e92fcc7ff956380992772 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 namespace wcf\system\user\notification\event;
+use wcf\system\email\mime\MimePartFacade;
+use wcf\system\email\mime\RecipientAwareTextMimePart;
 use wcf\system\request\LinkHandler;
 
 /**
@@ -51,20 +53,10 @@ class UserFollowFollowingUserNotificationEvent extends AbstractUserNotificationE
         * @inheritDoc
         */
        public function getEmailMessage($notificationType = 'instant') {
-               $authors = array_values($this->getAuthors());
-               $count = count($authors);
-               
-               if ($count > 1) {
-                       return $this->getLanguage()->getDynamicVariable('wcf.user.notification.follow.mail.stacked', [
-                               'author' => $this->author,
-                               'authors' => $authors,
-                               'count' => $count,
-                               'others' => $count - 1,
-                               'notificationType' => $notificationType
-                       ]);
-               }
-               
-               return $this->getLanguage()->getDynamicVariable('wcf.user.notification.follow.mail', ['author' => $this->author]);
+               return [
+                       'template' => 'email_notification_userFollowFollowing',
+                       'application' => 'wcf'
+               ];
        }
        
        /**
index 2d10d4357121858ecf6d5446774f41040162b443..d4a3c2f68c0dc5b1a5b4ff8e79674df0aefda0ed 100644 (file)
@@ -3234,24 +3234,38 @@ Die E-Mail-Adresse des neuen Benutzers lautet: {@$user->email}
        <category name="wcf.user.notification">
                <item name="wcf.user.notification.button.confirmed"><![CDATA[OK]]></item>
                <item name="wcf.user.notification.count"><![CDATA[if (data.returnValues.count == 0) { "Keine Benachrichtigungen" } else if (data.returnValues.count == 1) { "Eine Benachrichtigung" } else { data.returnValues.count + " Benachrichtigungen" }]]></item>
-               <item name="wcf.user.notification.follow.message"><![CDATA[{@$author->getAnchorTag()} folgt {if LANGUAGE_USE_INFORMAL_VARIANT}dir{else}Ihnen{/if}.]]></item>
-               <item name="wcf.user.notification.follow.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count == 2} und {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} und {@$authors[2]->getAnchorTag()}{/if}{else}{@$authors[0]->getAnchorTag()} und {#$others} weiteren{/if} folgen {if LANGUAGE_USE_INFORMAL_VARIANT}dir{else}Ihnen{/if}.]]></item>
-               <item name="wcf.user.notification.follow.title"><![CDATA[Neuer Follower]]></item>
-               <item name="wcf.user.notification.follow.title.stacked"><![CDATA[{#$count} neue Follower]]></item>
-               <item name="wcf.user.notification.follow.mail"><![CDATA[{@$author->username} folgt {if LANGUAGE_USE_INFORMAL_VARIANT}dir{else}Ihnen{/if}.]]></item>
-               <item name="wcf.user.notification.follow.mail.stacked"><![CDATA[{if $count < 4}{@$authors[0]->username}{if $count == 2} und {else}, {/if}{@$authors[1]->username}{if $count == 3} und {@$authors[2]->username}{/if}{else}{@$authors[0]->username} und {#$others} weiteren{/if} folgen {if LANGUAGE_USE_INFORMAL_VARIANT}dir{else}Ihnen{/if}.]]></item>
+               <item name="wcf.user.notification.markAllAsConfirmed"><![CDATA[Alle als gelesen markieren]]></item>
+               <item name="wcf.user.notification.markAllAsConfirmed.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} wirklich alle Benachrichtigungen als gelesen markieren?]]></item>
+               <item name="wcf.user.notification.markAsConfirmed"><![CDATA[Als gelesen markieren]]></item>
+               <item name="wcf.user.notification.noMoreNotifications"><![CDATA[Keine aktuellen Benachrichtigungen]]></item>
+               <item name="wcf.user.notification.noNotifications"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du hast{else}Sie haben{/if} keine Benachrichtigungen.]]></item>
+               <item name="wcf.user.notification.notifications"><![CDATA[Benachrichtigungen]]></item>
+               <item name="wcf.user.notification.notifications.description"><![CDATA[E-Mail-Benachrichtigungen werden nicht von allen verfügbaren Benachrichtigungen unterstützt.]]></item>
+               <item name="wcf.user.notification.notifications.disabled"><![CDATA[Deaktiviert]]></item>
+               <item name="wcf.user.notification.notifications.enabled"><![CDATA[Aktiviert]]></item>
+               <item name="wcf.user.notification.showAll"><![CDATA[Alle Benachrichtigungen anzeigen]]></item>
                <item name="wcf.user.notification.mail.disabled"><![CDATA[Die E-Mail-Benachrichtigung wurde erfolgreich abgeschaltet.]]></item>
+               <item name="wcf.user.notification.mailNotificationType.none"><![CDATA[Keine E-Mail-Benachrichtigung]]></item>
+               <item name="wcf.user.notification.mailNotificationType.instant"><![CDATA[Sofortige E-Mail-Benachrichtigung]]></item>
+               <item name="wcf.user.notification.mailNotificationType.daily"><![CDATA[Tägliche E-Mail-Benachrichtigung]]></item>
+               <item name="wcf.user.notification.mailNotificationType.notSupported"><![CDATA[E-Mail-Benachrichtigungen werden nicht unterstützt.]]></item>
                
-               <!-- Emails -->
+               <!-- Email Wrapper -->
                <item name="wcf.user.notification.mail.subject"><![CDATA[Neue Benachrichtigung: {@$title}]]></item>
                <item name="wcf.user.notification.mail.plaintext.intro"><![CDATA[Hallo {@$mailbox->getUser()->username},]]></item>
                <item name="wcf.user.notification.mail.plaintext.outro"><![CDATA[Diese E-Mail ist eine automatische Benachrichtigung. BITTE {if LANGUAGE_USE_INFORMAL_VARIANT}ANTWORTE{else}ANTWORTEN SIE{/if} NICHT AUF DIESE E-MAIL.
                
-{if LANGUAGE_USE_INFORMAL_VARIANT}Du kannst{else}Sie können{/if} die Einstellungen für {if LANGUAGE_USE_INFORMAL_VARIANT}deine{else}Ihre{/if} Benachrichtigungen auf {@PAGE_TITLE|language} unter folgender URL detailliert konfigurieren:
-{link controller='NotificationSettings' isEmail=true}{/link} 
+{if LANGUAGE_USE_INFORMAL_VARIANT}Besuchen Sie Ihre{else}Besuche deine{/if} Benachrichtigungseinstellungen [URL:{link controller='NotificationSettings' isEmail=true}{/link}], um die
+Benachrichtigungen auf {@PAGE_TITLE|language} [URL:{link isEmail=true}{/link}] nach {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Wünschen zu konfigurieren.
 
-{if LANGUAGE_USE_INFORMAL_VARIANT}Möchtest du{else}Möchten Sie{/if} diese E-Mail-Benachrichtigung in Zukunft nicht mehr erhalten, {if LANGUAGE_USE_INFORMAL_VARIANT}kannst du{else}können Sie{/if} folgenden Link aufrufen, um die Benachrichtigung abzuschalten:
-{link controller='NotificationDisable' isEmail=true}eventID={@$event->eventID}&userID={@$mailbox->getUser()->userID}&token={@$mailbox->getUser()->notificationMailToken}{/link}]]></item>
+Wenn {if LANGUAGE_USE_INFORMAL_VARIANT}du{else}Sie{/if} nur diese E-Mail-Benachrichtigung nicht mehr erhalten {if LANGUAGE_USE_INFORMAL_VARIANT}möchtest{else}möchten{/if}, dann {if LANGUAGE_USE_INFORMAL_VARIANT}kannst du{else}können Sie{/if} diese direkt abbestellen: {link controller='NotificationDisable' isEmail=true}eventID={@$event->eventID}&userID={@$mailbox->getUser()->userID}&token={@$mailbox->getUser()->notificationMailToken}{/link}.]]></item>
+               <item name="wcf.user.notification.mail.html.intro"><![CDATA[<h1>Hallo {$mailbox->getUser()->username},</h1>]]></item>
+               <item name="wcf.user.notification.mail.html.outro"><![CDATA[<p>Diese E-Mail ist eine automatische Benachrichtigung. <b>Bitte antworten Sie nicht auf diese E-Mail</b>.</p>
+
+<p>{if LANGUAGE_USE_INFORMAL_VARIANT}Besuche deine{else}Besuchen Sie Ihre{/if} <a href="{link controller='NotificationSettings' isEmail=true}{/link}">Benachrichtigungseinstellungen</a>, um die
+Benachrichtigungen auf <a href="{link isEmail=true}{/link}">{PAGE_TITLE|language}</a> nach {if LANGUAGE_USE_INFORMAL_VARIANT}deinen{else}Ihren{/if} Wünschen zu konfigurieren.</p>
+
+<p>Wenn {if LANGUAGE_USE_INFORMAL_VARIANT}du{else}Sie{/if} nur diese E-Mail-Benachrichtigung nicht mehr erhalten {if LANGUAGE_USE_INFORMAL_VARIANT}möchtest{else}möchten{/if}, dann {if LANGUAGE_USE_INFORMAL_VARIANT}kannst du{else}können Sie{/if} diese direkt <a href="{link controller='NotificationDisable' isEmail=true}eventID={@$event->eventID}&userID={@$mailbox->getUser()->userID}&token={@$mailbox->getUser()->notificationMailToken}{/link}">abbestellen</a>.</p>]]></item>
                <item name="wcf.user.notification.mail.daily.subject"><![CDATA[{if $count == 1}Neue Benachrichtigung{else}{#$count} neue Benachrichtigungen{/if}]]></item>
                <item name="wcf.user.notification.mail.daily.footer"><![CDATA[Diese E-Mail ist eine automatische Benachrichtigung. BITTE {if LANGUAGE_USE_INFORMAL_VARIANT}ANTWORTE{else}ANTWORTEN SIE{/if} NICHT AUF DIESE E-MAIL.
                
@@ -3260,23 +3274,16 @@ Die E-Mail-Adresse des neuen Benutzers lautet: {@$user->email}
 
 {if LANGUAGE_USE_INFORMAL_VARIANT}Möchtest du{else}Möchten Sie{/if} diese E-Mail-Benachrichtigung in Zukunft nicht mehr erhalten, {if LANGUAGE_USE_INFORMAL_VARIANT}kannst du{else}können Sie{/if} folgenden Link aufrufen, um die Benachrichtigung abzuschalten:
 {link controller='NotificationDisable' isEmail=true}userID={@$user->userID}&token={@$token}{/link}]]></item>
-       
-               <item name="wcf.user.notification.mailNotificationType.none"><![CDATA[Keine E-Mail-Benachrichtigung]]></item>
-               <item name="wcf.user.notification.mailNotificationType.instant"><![CDATA[Sofortige E-Mail-Benachrichtigung]]></item>
-               <item name="wcf.user.notification.mailNotificationType.daily"><![CDATA[Tägliche E-Mail-Benachrichtigung]]></item>
-               <item name="wcf.user.notification.mailNotificationType.notSupported"><![CDATA[E-Mail-Benachrichtigungen werden nicht unterstützt.]]></item>
-               <item name="wcf.user.notification.markAllAsConfirmed"><![CDATA[Alle als gelesen markieren]]></item>
-               <item name="wcf.user.notification.markAllAsConfirmed.confirmMessage"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Willst du{else}Wollen Sie{/if} wirklich alle Benachrichtigungen als gelesen markieren?]]></item>
-               <item name="wcf.user.notification.markAsConfirmed"><![CDATA[Als gelesen markieren]]></item>
-               <item name="wcf.user.notification.noMoreNotifications"><![CDATA[Keine aktuellen Benachrichtigungen]]></item>
-               <item name="wcf.user.notification.noNotifications"><![CDATA[{if LANGUAGE_USE_INFORMAL_VARIANT}Du hast{else}Sie haben{/if} keine Benachrichtigungen.]]></item>
-               <item name="wcf.user.notification.notifications"><![CDATA[Benachrichtigungen]]></item>
-               <item name="wcf.user.notification.notifications.description"><![CDATA[E-Mail-Benachrichtigungen werden nicht von allen verfügbaren Benachrichtigungen unterstützt.]]></item>
-               <item name="wcf.user.notification.notifications.disabled"><![CDATA[Deaktiviert]]></item>
-               <item name="wcf.user.notification.notifications.enabled"><![CDATA[Aktiviert]]></item>
-               <item name="wcf.user.notification.showAll"><![CDATA[Alle Benachrichtigungen anzeigen]]></item>
+
+               <!-- Notifications -->
                <item name="wcf.user.notification.com.woltlab.wcf.user"><![CDATA[Benutzer-Profile]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.user.follow.following"><![CDATA[Jemand folgt {if LANGUAGE_USE_INFORMAL_VARIANT}dir{else}Ihnen{/if}]]></item>
+               <item name="wcf.user.notification.follow.title"><![CDATA[Neuer Follower]]></item>
+               <item name="wcf.user.notification.follow.title.stacked"><![CDATA[{#$count} neue Follower]]></item>
+               <item name="wcf.user.notification.follow.message"><![CDATA[{@$author->getAnchorTag()} folgt {if LANGUAGE_USE_INFORMAL_VARIANT}dir{else}Ihnen{/if}.]]></item>
+               <item name="wcf.user.notification.follow.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count == 2} und {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} und {@$authors[2]->getAnchorTag()}{/if}{else}{@$authors[0]->getAnchorTag()} und {#$others} weiteren{/if} folgen {if LANGUAGE_USE_INFORMAL_VARIANT}dir{else}Ihnen{/if}.]]></item>
+               <item name="wcf.user.notification.follow.mail.plaintext"><![CDATA[{@$event->getAuthor()->username} [URL:{link controller='User' object=$event->getAuthor() isEmail=true}{/link}] folgt {if LANGUAGE_USE_INFORMAL_VARIANT}dir{else}Ihnen{/if}.]]></item>
+               <item name="wcf.user.notification.follow.mail.html"><![CDATA[<p><a href="{link controller='User' object=$event->getAuthor() isEmail=true}{/link}">{$event->getAuthor()->username}</a> folgt {if LANGUAGE_USE_INFORMAL_VARIANT}dir{else}Ihnen{/if}.</p>]]></item>
                <item name="wcf.user.notification.comment.title"><![CDATA[Neuer Kommentar (Pinnwand)]]></item>
                <item name="wcf.user.notification.comment.title.stacked"><![CDATA[{#$timesTriggered} neue Kommentare (Pinnwand)]]></item>
                <item name="wcf.user.notification.comment.message"><![CDATA[{if !$author->userID}Ein Gast{else}{@$author->getAnchorTag()}{/if} hat einen Kommentar an <a href="{link controller='User' object=$__wcf->getUser()}#wall{/link}">{if LANGUAGE_USE_INFORMAL_VARIANT}deiner{else}Ihrer{/if} Pinnwand</a> verfasst.]]></item>
index 1878d3f763d4878e386014b8173ea5fb2403132e..4d24c408111d95c18260305fc7f6025ff81b67fa 100644 (file)
@@ -3270,22 +3270,39 @@ Open the link below to access the user profile:
        <category name="wcf.user.notification">
                <item name="wcf.user.notification.button.confirmed"><![CDATA[OK]]></item>
                <item name="wcf.user.notification.count"><![CDATA[if (data.returnValues.count == 0) { "No Notifications" } else if (data.returnValues.count == 1) { "1 Notification" } else { data.returnValues.count + " Notifications" }]]></item>
-               <item name="wcf.user.notification.follow.message"><![CDATA[{@$author->getAnchorTag()} follows you.]]></item>
-               <item name="wcf.user.notification.follow.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count == 2} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} and {@$authors[2]->getAnchorTag()}{/if}{else}{@$authors[0]->getAnchorTag()} and {#$others} others{/if} follow you.]]></item>
-               <item name="wcf.user.notification.follow.mail"><![CDATA[{@$author->username} follows you.]]></item>
-               <item name="wcf.user.notification.follow.mail.stacked"><![CDATA[{if $count < 4}{@$authors[0]->username}{if $count == 2} and {else}, {/if}{@$authors[1]->username}{if $count == 3} and {@$authors[2]->username}{/if}{else}{@$authors[0]->username} and {#$others} others{/if} follow you.]]></item>
-               <item name="wcf.user.notification.follow.title"><![CDATA[New Follower]]></item>
-               <item name="wcf.user.notification.follow.title.stacked"><![CDATA[{#$count} new followers]]></item>
+               <item name="wcf.user.notification.markAllAsConfirmed"><![CDATA[Mark All as Read]]></item>
+               <item name="wcf.user.notification.markAllAsConfirmed.confirmMessage"><![CDATA[Do you really want to mark all notifications as read?]]></item>
+               <item name="wcf.user.notification.markAsConfirmed"><![CDATA[Mark as Read]]></item>
+               <item name="wcf.user.notification.noMoreNotifications"><![CDATA[No recent notifications.]]></item>
+               <item name="wcf.user.notification.noNotifications"><![CDATA[You have no notifications.]]></item>
+               <item name="wcf.user.notification.notifications"><![CDATA[Notifications]]></item>
+               <item name="wcf.user.notification.notifications.description"><![CDATA[Email notifications may not be supported for every available notification]]></item>
+               <item name="wcf.user.notification.notifications.disabled"><![CDATA[Disabled]]></item>
+               <item name="wcf.user.notification.notifications.enabled"><![CDATA[Enabled]]></item>
+               <item name="wcf.user.notification.showAll"><![CDATA[Display All Notifications]]></item>
                <item name="wcf.user.notification.mail.disabled"><![CDATA[Email notification has been disabled.]]></item>
-               <item name="wcf.user.notification.mail.footer"><![CDATA[This is an automatic notification, PLEASE DO NOT REPLY TO THIS EMAIL!
+               <item name="wcf.user.notification.mailNotificationType.none"><![CDATA[No Email Notification]]></item>
+               <item name="wcf.user.notification.mailNotificationType.instant"><![CDATA[Instant Email Notification]]></item>
+               <item name="wcf.user.notification.mailNotificationType.daily"><![CDATA[Daily Email Notification]]></item>
+               <item name="wcf.user.notification.mailNotificationType.notSupported"><![CDATA[Email Notifications are not supported.]]></item>
                
-You can manage your notification settings for {@PAGE_TITLE|language} on the page below:
-{link controller='NotificationSettings' isEmail=true}{/link} 
-
-If you do not want to receive further email notifications for this event, you can quickly disable it by opening the link below:
-{link controller='NotificationDisable' isEmail=true}eventID={@$notification->eventID}&userID={@$user->userID}&token={@$token}{/link}]]></item>
-               <item name="wcf.user.notification.mail.header"><![CDATA[Dear {@$user->username},]]></item>
+               <!-- Email Wrapper -->
                <item name="wcf.user.notification.mail.subject"><![CDATA[New Notification: {@$title}]]></item>
+               <item name="wcf.user.notification.mail.plaintext.intro"><![CDATA[Dear {@$mailbox->getUser()->username},]]></item>
+               <item name="wcf.user.notification.mail.plaintext.outro"><![CDATA[This is an automatic notification, PLEASE DO NOT REPLY TO THIS EMAIL!
+
+Visit your notification settings [URL:{link controller='NotificationSettings' isEmail=true}{/link}] to configure
+your notifications on {@PAGE_TITLE|language} [URL:{link isEmail=true}{/link}] as you wish.
+
+If you only wish to disable this type of notification you can do so by visiting:
+{link controller='NotificationDisable' isEmail=true}eventID={@$event->eventID}&userID={@$mailbox->getUser()->userID}&token={@$mailbox->getUser()->notificationMailToken}{/link}]]></item>
+               <item name="wcf.user.notification.mail.html.intro"><![CDATA[<h1>Dear {$mailbox->getUser()->username},</h1>]]></item>
+               <item name="wcf.user.notification.mail.html.outro"><![CDATA[<p>This is an automatic notification, <b>please do not reply to this email</b>!</p>
+
+<p>Visit your <a href="{link controller='NotificationSettings' isEmail=true}{/link}">notification settings</a> to configure
+your notifications on <a href="{link isEmail=true}{/link}">{PAGE_TITLE|language}</a> as you wish.</p>
+
+<p>You can <a href="{link controller='NotificationDisable' isEmail=true}eventID={@$event->eventID}&userID={@$mailbox->getUser()->userID}&token={@$mailbox->getUser()->notificationMailToken}{/link}">disable only this type of notification</a> as well.</p>]]></item>
                <item name="wcf.user.notification.mail.daily.subject"><![CDATA[{if $count == 1}New Notification{else}{#$count} New Notifications{/if}]]></item>
                <item name="wcf.user.notification.mail.daily.footer"><![CDATA[This is an automatic notification, PLEASE DO NOT REPLY TO THIS EMAIL!
                
@@ -3294,22 +3311,16 @@ You can manage your notification settings for {@PAGE_TITLE|language} on the page
 
 If you do not want to receive further email notifications for this event, you can quickly disable it by opening the link below:
 {link controller='NotificationDisable' isEmail=true}userID={@$user->userID}&token={@$token}{/link}]]></item>
-               <item name="wcf.user.notification.mailNotificationType.none"><![CDATA[No Email Notification]]></item>
-               <item name="wcf.user.notification.mailNotificationType.instant"><![CDATA[Instant Email Notification]]></item>
-               <item name="wcf.user.notification.mailNotificationType.daily"><![CDATA[Daily Email Notification]]></item>
-               <item name="wcf.user.notification.mailNotificationType.notSupported"><![CDATA[Email Notifications are not supported.]]></item>
-               <item name="wcf.user.notification.markAllAsConfirmed"><![CDATA[Mark All as Read]]></item>
-               <item name="wcf.user.notification.markAllAsConfirmed.confirmMessage"><![CDATA[Do you really want to mark all notifications as read?]]></item>
-               <item name="wcf.user.notification.markAsConfirmed"><![CDATA[Mark as Read]]></item>
-               <item name="wcf.user.notification.noMoreNotifications"><![CDATA[No recent notifications.]]></item>
-               <item name="wcf.user.notification.noNotifications"><![CDATA[You have no notifications.]]></item>
-               <item name="wcf.user.notification.notifications"><![CDATA[Notifications]]></item>
-               <item name="wcf.user.notification.notifications.description"><![CDATA[Email notifications may not be supported for every available notification]]></item>
-               <item name="wcf.user.notification.notifications.disabled"><![CDATA[Disabled]]></item>
-               <item name="wcf.user.notification.notifications.enabled"><![CDATA[Enabled]]></item>
-               <item name="wcf.user.notification.showAll"><![CDATA[Display All Notifications]]></item>
+
+               <!-- Notifications -->
                <item name="wcf.user.notification.com.woltlab.wcf.user"><![CDATA[User Profiles]]></item>
                <item name="wcf.user.notification.com.woltlab.wcf.user.follow.following"><![CDATA[Notify when I receive a new follower]]></item>
+               <item name="wcf.user.notification.follow.title"><![CDATA[New Follower]]></item>
+               <item name="wcf.user.notification.follow.title.stacked"><![CDATA[{#$count} new followers]]></item>
+               <item name="wcf.user.notification.follow.message"><![CDATA[{@$author->getAnchorTag()} follows you.]]></item>
+               <item name="wcf.user.notification.follow.message.stacked"><![CDATA[{if $count < 4}{@$authors[0]->getAnchorTag()}{if $count == 2} and {else}, {/if}{@$authors[1]->getAnchorTag()}{if $count == 3} and {@$authors[2]->getAnchorTag()}{/if}{else}{@$authors[0]->getAnchorTag()} and {#$others} others{/if} follow you.]]></item>
+               <item name="wcf.user.notification.follow.mail.plaintext"><![CDATA[{@$event->getAuthor()->username} [URL:{link controller='User' object=$event->getAuthor() isEmail=true}{/link}] is following you.]]></item>
+               <item name="wcf.user.notification.follow.mail.html"><![CDATA[<a href="{link controller='User' object=$event->getAuthor() isEmail=true}{/link}">{$event->getAuthor()->username}</a> is following you.]]></item>
                <item name="wcf.user.notification.comment.title"><![CDATA[New Comment (Wall)]]></item>
                <item name="wcf.user.notification.comment.title.stacked"><![CDATA[{#$timesTriggered} new comments (Wall)]]></item>
                <item name="wcf.user.notification.comment.message"><![CDATA[{if !$author->userID}A guest{else}{@$author->getAnchorTag()}{/if} wrote a comment on <a href="{link controller='User' object=$__wcf->getUser()}#wall{/link}">your wall</a>.]]></item>