Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Try Vanilla Forums Cloud product

I just want to add a single line of text after email notifications

Hi,

I'm new here, and I'm liking Vanilla a lot.
I have being about 48 days sniffing the web and this forums looking for how to modify the email texts.
Non of the old discussions about this where clear enough or updated, leading me to dark unkown places in the PHP code (wich I dont understand) without any successful results.

Would be nice to be able to change the whole and all email templates, BUT i'm I'll happy just adding a line of text at the end of email notifications.

Can someone please help me?

Regards

Comments

  • x00x00 MVP
    edited November 9

    Yeah...about that.

    It used to be easy, but now email template are a bit of a mess TBH. :/

    Personally my favoured method, is to override the template class (yes the actual class not a temperate itself), but that is not for everybody. Technically you can create your own and assign, if but if you do that, you can just as easily predefine the default.

    The whole rush to provide a click button solution html email mean there is string concatenation harded coded rather then yielded variables. Thier button based html messages poorly translate to text based / or mixed content messages. They don't make much sense.

    The previous method was all locale / definition based.

    I'm not opposed to templates either it is just the implementation is unfortunate.

    grep is your friend.

    piXelicidio
  • R_JR_J Cheerleader & Troubleshooter Munich Moderator

    It's not easy, but it is absolutely possible.

    But since it is not easy, you need to be more specific what your requirements are. Do you want to include a common text at the end of the mail or do you want to include something which is recipient specific?
    Should that be at the end of every mail or only at the end of some new PN notifications or other specific event mails?
    Are you using html mails or plain text mails?

    K17
  • Hi, thanks for replaying.
    I just need to add a line of text with a link to unsubscribe or edit notifications. Thats my only main concern.

  • R_JR_J Cheerleader & Troubleshooter Munich Moderator

    Start with the example plugin and add the following method:

        public function gdn_email_beforeSendMail_handler($sender) {
            $emailTemplate = $sender->getEmailTemplate();
    
            // Get message as it currently is.
            $message = $emailTemplate->getMessage();
    
            // Change it.
            $preferenceUrl = url('/profile/notifications', true);
            $message = "{$message}<br />You can change mail notification preferences here: {$preferenceUrl}";
    
            // Apply changed message to the template.
            $emailTemplate->setMessage($message);
        }
    
    piXelicidio
  • You are leading me to my first plugin?! O.o awesome and scary :D
    Thanks

    (creating backup...)

    R_J
  • (20 minutes later)... I found the example plugin! :D

  • Trying to not touching anything on the example plugin and added your function after public function discussionsController_afterDiscussionTitle_handler($sender)
    The example plugin functionality works but not the email modification. Tryied also switching to HTML emails and nothing. :( Maybe I have to do something else other than pasting the code there, but I donn't have any idea.

  • But I'm sure handler is called because I changed "getEmailTemplate()" for "emailTemplate()" and email notification stopped on the forum, until I set it back again to getEmailTemplate().
    So maybe setMessage() is the one not working.

  • edited November 22

    Finally I did it! SOLVED! :D
    Was not of my wish to write PHP but you gave me the motivation to be brave.
    I did a search on all vanilla files to find where the event beforeSendMail is triggered.
    Found it on: class.email.php

        public function send($eventName = '') {
            $this->formatMessage($this->emailTemplate->toString());
            $this->fireEvent('BeforeSendMail');
            ...
    

    After noticing "toString()" there I got attracted to try something and after studing your code I modifed this core funciton with:

        public function send($eventName = '') {
            $mystring = $this->emailTemplate->toString();
            $preferenceUrl = url('/profile/preferences', true);
            $mystring = "{$mystring}\r\n\n You can change email notification preferences here: {$preferenceUrl}";
            $this->formatMessage($mystring);
            ...
    

    And it successfully worked! :D :proud:
    Thank you!

    Maybe that's not good thing to do, modifying the core files, but I was very anxious to resolve this someway!
    And I'm wondering why more people are not complaining about this, something so basic and essential as provide easly modifying the email templates.

  • x00x00 MVP
    edited November 22

    @piXelicidio

    don't modify the core, istead, the way to to do it. Is create an addon, and include a copy of this file. If it is already the auto load will not try to load the core file.

    Also you are modifying the wrong file. Leave class.email.php alone. Instead copy class.emailtemplate.php and change that.

    e.g. if you make an and app you can put in the library folder. then include in in your apps settings/boostrap.php put

    require_once PATH_APPLICATIONS.DS.'yourappname'.DS.'library'.DS.'class.emailtemplate.php';

    changing yourappname to the name of the app

    grep is your friend.

  • R_JR_J Cheerleader & Troubleshooter Munich Moderator
    edited November 22

    @piXelicidio No, you were so close!

    Never ever change the core files. That will only lead to confusion on the next update and maybe even to severe problems if not done without exactly knowing what you are doing.

    I hope you still have your example plugin? There is only one line missing:

    @R_J said:
    Start with the example plugin and add the following method:

        public function gdn_email_beforeSendMail_handler($sender) {
            $emailTemplate = $sender->getEmailTemplate();
    
            // Get message as it currently is.
            $message = $emailTemplate->getMessage();
    
            // Change it.
            $preferenceUrl = url('/profile/notifications', true);
            $message = "{$message}\r\n\r\nYou can change mail notification preferences here: {$preferenceUrl}";
    
            // Apply changed message to the template.
            $emailTemplate->setMessage($message);
            // Re-render the mail.
           $sender->formatMessage($emailTemplate->toString());
        }
    

    By the way: you should delete every other method in that example plugin.

    @x00 you can set a custom template by using the same event:

        public function gdn_email_beforeSendMail_handler($sender) {
            $emailTemplate = $sender->getEmailTemplate();
    
            $customViewLocation = Gdn::Controller()->fetchViewLocation(
                'email-basic-custom',
                '',
                'plugins/customemailtemplate' // ... or whatever...
            );
            $emailTemplate->setView($customViewLocation );
    
            $sender->formatMessage($emailTemplate->toString());
        }
    
  • Ok... ok,, no core files modifications... (if... something else work :D )

    @x00
    Thanks for the help, but I can't follow, don't know how to do half of what you're telling me :)

    @R_J
    Added the line, and it works! but the extra line appears before "check it out" :confused:

    By the way: you should delete every other method in that example plugin.

    There are many funcitons there, can I delete actually every other of them? Leaving gdn_email_beforeSendMail... isolated?

  • R_JR_J Cheerleader & Troubleshooter Munich Moderator

    I will investigate on the "Check it out"

    Your minimum and absolutely functionless plugin can look like this:

    class ExamplePlugin extends Gdn_Plugin {
    }
    

    So yes, you can delete all other methods and only use the above.

    piXelicidio
  • R_JR_J Cheerleader & Troubleshooter Munich Moderator

    The solution is public function setFooter($text, $textColor = '', $backgroundColor = '')

        public function gdn_email_beforeSendMail_handler($sender) {
            $emailTemplate = $sender->getEmailTemplate();
    
            // $message = $emailTemplate->getMessage();
    
            $preferencesLink = url('/profile/preferences');
            $preferencesText = sprintf(
                // t("\r\nYou can change your email settings here: %s"),
                t('<br />You can change your email settings <a href="%s">here</a>'),
                $preferencesLink
            );
    
            $emailTemplate->setFooter($preferencesText);
    
            // Re-render the mail.
            $sender->formatMessage($emailTemplate->toString());
        }
    

    Investigate (not change :wink: ) the class.emailtemplate.php and you might find other helpful ways to alter that mail

  • R_JR_J Cheerleader & Troubleshooter Munich Moderator

    @piXelicidio said:
    There are many funcitons there, can I delete actually every other of them? Leaving gdn_email_beforeSendMail... isolated?

    And what I forgot to add: that is what's making it easy to extend Vanilla!

  • R_JR_J Cheerleader & Troubleshooter Munich Moderator

    If you prefer, you can turn off HTML mails again. They are not needed if you want to customize mails and your short plugin should work with plain text mails, too

  • There is line of text added to the end of the email, but it only says: "Array" :(
    Tried to replace the printf with the previous way of concatenating strings and shows the same line: "Array" :(

  • Sending a literal string to setFooter also show the same thing "Array"

  • hey! it works, but only when switching to HTML emails...

  • edited November 22

    Ok, good news, made it work with plain text too.
    Using "if" condition to know when mail is plain text (thanks to class.emailtemplate.php research ) :proud:
    Then concatenate string if plain text or use setFooter when HTML mode is active.

    class emailprefPlugin extends Gdn_Plugin {  
       public function gdn_email_beforeSendMail_handler($sender) {
            $emailTemplate = $sender->getEmailTemplate();        
            $preferencesLink = url('/profile/preferences', true); //link are broken without 'true'
            $preferencesText = sprintf( t('
    You can change your email settings here'), $preferencesLink ); if ($emailTemplate->isPlaintext()) { $plainEmail = $emailTemplate->toString(); $plainEmail = "{$plainEmail}\r\n\n You can change your email settings here: {$preferencesLink}"; $sender->formatMessage($plainEmail); } else { $emailTemplate->setFooter($preferencesText); // Re-render the mail. $sender->formatMessage($emailTemplate->toString()); } } }

    Working perfeclty! :+1: Thank you @R_J
    You need to publish this plugin :) I guess many people will find it useful, addind a config menu to custommize the text line and call it "The email footer plugin" :proud:

    R_J
  • R_JR_J Cheerleader & Troubleshooter Munich Moderator

    Awesome and congratulations!

    I think about creating a "custom email template" plugin

    piXelicidio
  • Thanks!
    Email template plugin that allows you to customize all email comunication from dashboard would be great!

  • R_JR_J Cheerleader & Troubleshooter Munich Moderator

    Not that nifty.

    The plugin is essentially ready, I have uploaded it so that you can see it here: https://github.com/R-J/customemailtemplate

    It's not much more than I have shown above, only that I want to add the user information to the message, so that they can be personalized better.

    I plan to add some example templates and make them switchable in the dashboard. Admins would be able to add their own templates and choose them as the default template.

    piXelicidio
  • x00x00 MVP
    edited November 23

    @R_J said:

    @x00 you can set a custom template by using the same event:

    I'm aware of that, however, hooks aren't the be and end all. It is just as easy to pre-define the class.

    In fact dependency injection is a far better approach then hooks. Predefining isn't quite dependency injection but almost.

    grep is your friend.

Sign In or Register to comment.