استبدال email/notification.html عبر إضافة مخصصة - نصائح؟

I’ve reached a bit of an impasse and I’m looking for a spot of help.

As part of our switchover to Discourse, we want to change the design of the default email templates and obviously, as only the copy can be changed via the control panel, we figured we’d need to substitute the email templates by building a plugin that allows our email templates to persist between upgrades.

I’ve sussed out how to override the digests, thanks to this thread here:

…however, this doesn’t help when it comes to the notification.html.erb template, which seems to be impervious to ::ActionMailer::Base.prepend_view_path.

Poking into the business end of user_notifications.rb, I noticed this:

html = UserNotificationRenderer.new(Rails.configuration.paths["app/views"]).render(
          template: 'email/notification',
          format: :html,
          locals: { context_posts: context_posts,
                    reached_limit: reached_limit,
                    post: post,
                    in_reply_to_post: in_reply_to_post,
                    classes: Rtl.new(user).css_class
          }
)

I assume this is what is responsible for setting the location of the template file to be used, but see no obvious way to manipulate this without overriding the method in a plugin and admittedly, my experience with Ruby is somewhat limited, so any help you could provide would be very much appreciated.

I believe we have plans to make email templates more customizable in the near future, don’t we @awesomerobot?

Well, since yesterdaty, I’ve managed to make something happen. I don’t think it’s particularly clean, but here it is.

In my plugin.rb file:

# This attempts to override the Notification Emails by sliding in 
# our custom template directory first.
require_dependency 'user_notifications'
module ::UserNotificationsOverride
    def send_notification_email(opts)
        Rails.configuration.paths["app/views"].unshift(File.expand_path("../templates", __FILE__))
        super(opts)
    end
end

class ::UserNotifications
    prepend ::UserNotificationsOverride
end

…and then adjacent to the plugin file is a template/ directory that contains customised .erb files using the same structure as below /app/views. So my plugin now looks like:

/my-email-plugin
├── plugin.rb
└── templates
    └── email
        ├── _post.html.erb
        ├── invite.html.erb
        ├── notification.html.erb
        └── template.html.erb

What I wanted to do was shift my custom templates folder ahead of the default, in an attempt to replicate what the ::ActionMailer::Base.prepend_view_path line was doing, but without breaking anything else or by carbon-copying the entire send_notification_email method for the sake of changing one line.

If you can think of any ways to improve this, then please do share. :slight_smile:

هل نجح هذا معك، وهل لا يزال يعمل؟

لقد حاولت إنشاء ملحق باستخدام الكود الخاص بك في plugin.rb وهيكل القوالب، ولكن عند محاولة إعادة بناء التطبيق بعد إضافة الملحق في containers/app.yml، فشل العملية بالخطأ التالي:

LoadError: لا يوجد ملف لتحميله – user_notifications.rb

لقد عرفت ما كانت المشكلة. يجب وضع كود plugin.rb داخل after_initialize:

after_initialize do
    require_dependency 'user_notifications'
    module ::UserNotificationsOverride
        def send_notification_email(opts)
            Rails.configuration.paths["app/views"].unshift(File.expand_path("../templates", __FILE__))
            super(opts)
        end
    end

    class ::UserNotifications
        prepend ::UserNotificationsOverride
    end
end

يعمل هذا الآن بشكل جيد بالنسبة لي. شكرًا لمشاركة هذه الطريقة!

ملاحظة: قام @neil للتو بدمج هذا:

هل تحل هذه الميزة الأساسية الجديدة الحاجة الأساسية التي دفعتك لإنشاء هذه الإضافة؟

لا تزال محتويات قوالب notification.html.erb و _*post.html.erb غير قابلة للتخصيص، لذا سنحتاج إلى إيجاد طريقة لحل هذه المسألة في الجزء الثاني من عمل تخصيص البريد الإلكتروني.