Metadata-Version: 1.1
Name: wagtail-birdsong
Version: 0.1.2
Summary: Create and send email campaigns from Wagtail
Home-page: UNKNOWN
Author: Jonny Scholes
Author-email: jonny@neonjungle.studio
License: BSD License
Description: .. image:: docs/birdsong.svg
            :width: 400
            :alt: Birdsong Logo
        
        A plugin for wagtail that allows you to create, send, preview, edit and test email campaigns from within Wagtail.
        Campaign templates are created using `mjml <https://mjml.io/>`_.
        
        Basic usage
        ===========
        
        Install birdsong:
        
        .. code-block:: shell
            
            pip install wagtail-birdsong
        
        
        Add the following to your installed apps:
        
        .. code-block:: python
        
            'mjml',
            'birdsong',
            'wagtail.contrib.modeladmin',
        
        
        Make a new app e.g. ``email``, create a ``models.py`` with a model that extends the included ``Campaign`` model. Some compatible mjml streamfield blocks are included in birdsong for convenience.
        
        .. code-block:: python
        
            from birdsong.blocks import DefaultBlocks
            from birdsong.models import Campaign
            from django.db import models
            from wagtail.admin.edit_handlers import StreamFieldPanel
            from wagtail.core.fields import StreamField
        
        
            class SaleEmail(Campaign):
                body = StreamField(DefaultBlocks())
        
                panels = Campaign.panels + [
                    StreamFieldPanel('body'),
                ]
        
        Then in the same app, create a ``wagtail_hooks.py`` if it doesn't exist, this is where the admin is created
        for content editors to create/edit/send campaigns.
        
        The ``CampaignAdmin`` is just an extension of Wagtail's ``ModelAdmin`` class so most of the same options are available for overriding functionality.
        
        .. code-block:: python
        
            from wagtail.contrib.modeladmin.options import modeladmin_register
            from birdsong.options import CampaignAdmin
        
            from .models import SaleEmail
        
        
            @modeladmin_register
            class SaleEmailAdmin(CampaignAdmin):
                campaign = SaleEmail
                menu_label = 'Sale Email'
                menu_icon = 'mail'
                menu_order = 200
        
        
        Create your campaign template in ``{app_folder}/templates/mail/{model_name}.html`` e.g. ``email/templates/mail/sale_email.html``,
        alternatively override the ``get_template`` method on your campaign model.
        
        Campaign templates use django-mjml for responsive, well designed emails. To read up how to setup django-mjml you can read the docs `here <https://github.com/liminspace/django-mjml>`_. There is a base template included in Birdsong that can be extended.
        
        ``sale_email.html``
        
        .. code-block:: html
        
            {% extends "birdsong/mail/base_email.html" %}
        
            {% block email_body %}
            <mj-section>
                <mj-column>
                    <mj-text>Hello {{ contact.email }}!</mj-text>
                    {% for b in self.body %}
                        {{ b }}
                    {% endfor %}
                </mj-column>
            </mj-section>
            {% endblock email_body %}
        
        
        You're now ready to go!
        
        .. image:: docs/birdsong-preview.png
            :width: 900
            :alt: Screenshot
        
        
        
        Custom Contact models
        =====================
        
        By default the included ``Contact`` model is used for every campaign, but you may want to store extra data, like names and preferences. 
        You can override the default ``Contact`` model by setting an option on the admin for your campaign:
        
        ``models.py``
        
        .. code-block:: python
        
            from birdsong.models import Contact
            from django.db import models
        
            class ExtendedContact(Contact):
                first_name = models.CharField(max_length=255)
                last_name = models.CharField(max_length=255)
                location = models.CharField(max_length=255)
        
        
        ``wagtail_hooks.py``
        
        .. code-block:: python
        
            from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register
            from birdsong.options import CampaignAdmin
        
            from .models import ExtendedContact, SaleEmail
        
        
            @modeladmin_register
            class SaleEmailAdmin(CampaignAdmin):
                campaign = SaleEmail
                menu_label = 'Sale Email'
                menu_icon = 'mail'
                menu_order = 200
                contact_class = ExtendedContact
        
        
            # You may want to add your own modeladmin here to list/edit/add contacts
            @modeladmin_register
            class ContactAdmin(ModelAdmin):
                model = ExtendedContact
                menu_label = 'Contacts'
                menu_icon = 'user'
                list_diplay = ('email', 'first_name', 'last_name', 'location')
        
        
        Filtering on contact properties
        ===============================
        
        You might want to only send a campaign to a subset of your ``Contact`` models. Creating a filter using `django-filter <https://django-filter.readthedocs.io/en/master/>`_ and adding it to the ``CampaignAdmin`` allows users to filter on any property.
        
        ``filters.py``
        
        .. code-block:: python
        
            from django_filters import FilterSet
            from django_filters.filters import AllValuesFilter
        
            from .models import ExtendedContact
        
        
            class ContactFilter(FilterSet):
                location = AllValuesFilter()
        
                class Meta:
                    model = ExtendedContact
                    fields = ('location',)
        
        
        ``wagtail_hooks.py``
        
        .. code-block:: python
        
            from wagtail.contrib.modeladmin.options import modeladmin_register
            from birdsong.options import CampaignAdmin
        
            from .filters import ContactFilter
            from .models import ExtendedContact, SaleEmail
        
        
            @modeladmin_register
            class SaleEmailAdmin(CampaignAdmin):
                campaign = SaleEmail
                menu_label = 'Sale Email'
                menu_icon = 'mail'
                menu_order = 200
                contact_class = ExtendedContact
                contact_filter_class = ContactFilter
        
        
        Users will now be able to send campaigns to a subset of contacts base on location.
        
        Unsubscribe url
        ===============
        
        Included in birdsong is a basic way for contacts to unsubscribe, just include the url configuration and add the unsubscribe url to your email template.
        
        ``urls.py``
        
        .. code-block:: python
        
            from birdsong import urls as birdsong_urls
            from django.urls import include, path
        
            urlpatterns = [
                ...
                path('mail/', include(birdsong_urls)),
                ...
            ]
        
        ``sale_email.html``
        
        .. code-block:: html
        
            {% extends "birdsong/mail/base_email.html" %}
        
            {% block email_body %}
            <mj-section>
                <mj-column>
                    <mj-text>Hello {{ contact.email }}!</mj-text>
                    {% for b in self.body %}
                        {{ b }}
                    {% endfor %}
                </mj-column>
            </mj-section>
            <mj-section>
                Click <a href="{{ site.full_url }}{% url 'birdsong:unsubscribe' contact.id %}">here</a> to unsubscribe.
            </mj-section>
            {% endblock email_body %}
        
        
        
        
        Future features:
        ----------------
        
        - More tests!
        - Proper docs
        - Backends other thans SMTP for sending emails so analytics can be gathered (email opened, bounced etc)
        - Reloading the preview on edit
        - Broader permissions for campaigns (send, preview, test send)
        
Platform: UNKNOWN
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Framework :: Django
Classifier: License :: OSI Approved :: BSD License
