Search code examples
djangomezzanine

Easiest strat to add a Subscribe module to a Mezzanine blog


I have a Mezzanine blog and I would like to add a little form to every page so users can type their email addresses and click 'subscribe' so, from that moment, an email will be sent to announce any new post to the blog.

I don't see that built in or any existing module for that purpose... Should I program that from scratch? Any ideas?


Solution

  • Since there are no answers, I will try to offer my best guess as to the easiest strategy in this situation. I don't know of any built-in functions in Mezzanine that perform this specific function, so here's how I would approach it:

    1. python manage.py startapp subscriber
    2. Build out basic model - email = models.EmailField(unique=True), etc.
    3. Create basic admin.py
    4. Update settings.py -> INSTALLED_APPS and ADMIN_MENU_ORDER

      ADMIN_MENU_ORDER = (
          (_("Web Content"), ((_("Pages"), "pages.Page"),
              (_("Subscribers"), "subscriber.Subscriber"),
      
    5. Create a forms.py - something like this:

      class SubscriberForm(forms.ModelForm):
          class Meta:
              model = Subscriber
              fields = ['email']
      
    6. Setup a views.py for GET/POST of above form

    7. Reconfigure urls.py to redirect to the new view function
    8. Then, perhaps the only interesting part of my response, I would copy the Mezzanine Blog app directory into the project directory, and create a signals.py. Maybe add something like this:

      @receiver(pre_save, sender=BlogPost, dispatch_uid="save_blogpost")
      def save_blogpost(sender, instance, **kwargs):
          """ Every time a new blog post is created, notify all subscribers."""
          if instance.published:
              subs = Subscriber.objects.all()
              for sub in subs:
                  email = EmailMultiAlternatives(
                      subject="New Blog Post!",
                      body="A new blog post has been added!",
                      from_email="example@email.com",
                      to=[sub.email]
                  )
                  email.attach_alternative(self.body, "text/html")
                  email.send()
      
    9. Update app.py in the blog app directory to contain this under the Config class:

      def ready(self):
          import blog.signals  # noqa
      

    If you've got Django configured to send mail through an external SMTP mail server, that's easier. If not, you'll likely want to setup Postfix with OpenDKIM and configure SPF to reduce probability the outgoing mail ends up in spam.

    (Also, you'll obviously need to handle situations where an admin changes a draft post to a published post, etc.)

    Not sure if this helps, but hopefully!