Beispiel #1
0
class NewsIndex(Page):
    intro = RichTextField(blank=True)
    press_kit = models.ForeignKey('wagtaildocs.Document',
                                  null=True,
                                  blank=True,
                                  on_delete=models.SET_NULL,
                                  related_name='+')

    @property
    def articles(self):
        articles = NewsArticle.objects.live().child_of(self)
        article_data = {}
        for article in articles:
            article_data['news/{}'.format(article.slug)] = {
                'date': article.date,
                'heading': article.heading,
                'subheading': article.subheading,
                'pin_to_top': article.pin_to_top,
                'article_image': article.article_image,
                'author': article.author,
                'tags': [tag.name for tag in article.tags.all()],
            }
        return article_data

    content_panels = Page.content_panels + [
        FieldPanel('intro', classname="full"),
        DocumentChooserPanel('press_kit'),
    ]

    api_fields = (
        'intro',
        'press_kit',
        'articles',
        'slug',
        'seo_title',
        'search_description',
    )

    subpage_types = ['news.NewsArticle']
    parent_page_types = ['pages.HomePage']
Beispiel #2
0
class HomePageGalleryItem(Orderable):
    THEME_CHOICES = (
        ('dark', 'Dark'),
        ('light', 'Light'),
    )
    
    image = models.ForeignKey(
        'wagtailimages.Image',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        help_text="Minimum 1920px wide"
    )
    link_page = models.ForeignKey(
        'wagtailcore.Page',
        null=True,
        blank=True,
        related_name='+',
        help_text='Add if you want this item to link to a page on this site.'
    )

    video_hd_url = models.URLField(blank=True,
        help_text='High Definition URL from a video streaming service such as Vimeo.')
    video_sd_url = models.URLField(blank=True,
        help_text='Standard Definition URL from a video streaming service such as Vimeo.')
    caption = RichTextField(features=['bold', 'italic'])
    theme = models.CharField(max_length=255, choices=THEME_CHOICES, default='light')
    page = ParentalKey('home.HomePage', related_name='slideshow_images')

    panels = [
        ImageChooserPanel('image'),
        MultiFieldPanel([
            FieldPanel('video_hd_url'),
            FieldPanel('video_sd_url'),
        ], heading="Video"),
        FieldPanel('caption'),
        FieldPanel('theme'),
        PageChooserPanel('link_page'),
    ]
Beispiel #3
0
 class BaseFieldsMixin(models.Model):                                                                                                                                                                                                        
     header_title = models.CharField(max_length=512, blank=True)                                                                                                                                                                             
     header_slogan = models.CharField(max_length=512, blank=True)                                                                                                                                                                            
     header_img = models.ForeignKey(                                                                                                                                                                                                         
         'wagtailimages.Image',                                                                                                                                                                                                              
         null=True,                                                                                                                                                                                                                          
         blank=True,                                                                                                                                                                                                                         
         on_delete=models.SET_NULL,                                                                                                                                                                                                          
         related_name='+'                                                                                                                                                                                                                    
     )                                                                                                                                                                                                                                       
     hide_navigation = models.BooleanField(default=False)                                                                                                                                                                                    
     footer_text = RichTextField(blank=True)                                                                                                                                                                                                 
                                                                                                                                                                                                                                             
     settings_panels = [                                                                                                                                                                                                                     
         MultiFieldPanel([                                                                                                                                                                                                                   
             FieldPanel('hide_navigation'),                                                                                                                                                                                                  
         ] + Page.settings_panels, "Page settings"),                                                                                                                                                                                         
     ]                                                                                                                                                                                                                                       
                                                                                                                                                                                                                                             
     content_panels = [                                                                                                                                                                                                                      
         MultiFieldPanel(                                                                                                                                                                                                                    
             [                                                                                                                                                                                                                               
                 FieldPanel('header_title', classname="full"),                                                                                                                                                                               
                 FieldPanel('header_slogan', classname="full"),                                                                                                                                                                              
                 ImageChooserPanel('header_img'),                                                                                                                                                                                            
             ],                                                                                                                                                                                                                              
             heading='Header elements', classname="collapsible collapsed"                                                                                                                                                                    
         ),                                                                                                                                                                                                                                  
         MultiFieldPanel(                                                                                                                                                                                                                    
             [                                                                                                                                                                                                                               
                 FieldPanel('footer_text', classname="full"),                                                                                                                                                                                
             ],                                                                                                                                                                                                                              
             heading='Footer elements', classname="collapsible collapsed"                                                                                                                                                                    
         ),                                                                                                                                                                                                                                  
         FieldPanel('title', classname="full title"),                                                                                                                                                                                        
                                                                                                                                                                                                                                             
     ]                                                                                                                                                                                                                                       
                                                                                                                                                                                                                                             
     class Meta:                                                                                                                                                                                                                             
         abstract = True                                                                                                                                                                                                                     
Beispiel #4
0
class SiteSettings(BaseSetting):
    google_analytics_id = models.CharField(
        max_length=255,
        help_text='Your Google Analytics ID. Example: UA-12345',
        blank=True)
    website_header_text = models.CharField(
        max_length=255, blank=True, help_text='The title of your website')
    website_header_icon = models.ForeignKey('wagtailimages.Image',
                                            null=True,
                                            blank=True,
                                            on_delete=models.SET_NULL,
                                            related_name='+')
    website_footer = RichTextField(blank=True)
    website_favicon = models.ForeignKey('wagtailimages.Image',
                                        null=True,
                                        blank=True,
                                        on_delete=models.SET_NULL,
                                        related_name='+')
    algolia_app_id = models.CharField(max_length=255,
                                      help_text='Your Algolia.com App ID',
                                      default='',
                                      blank=True)
    algolia_public_key = models.CharField(
        max_length=255,
        help_text='Your Algolia.com public key (NOT private key)',
        default='',
        blank=True)

    panels = [
        FieldPanel('website_header_text'),
        ImageChooserPanel('website_header_icon'),
        FieldPanel('google_analytics_id'),
        RichTextFieldPanel('website_footer'),
        ImageChooserPanel('website_favicon'),
        FieldPanel('algolia_app_id'),
        FieldPanel('algolia_public_key'),
    ]

    def favicon(self):
        return Image.objects.get(file='original_images/favicon.ico.png')
Beispiel #5
0
class BlogIndexPage(Page):
    intro = RichTextField(blank=True)

    search_fields = Page.search_fields + [
        index.SearchField('intro'),
    ]

    @property
    def blogs(self):
        # Get list of live blog pages that are descendants of this page
        blogs = BlogPage.objects.live().descendant_of(self)

        # Order by most recent date first
        blogs = blogs.order_by('-date')

        return blogs

    def get_context(self, request):
        # Get blogs
        blogs = self.blogs

        # Filter by tag
        tag = request.GET.get('tag')
        if tag:
            blogs = blogs.filter(tags__name=tag)

        # Pagination
        page = request.GET.get('page')
        paginator = Paginator(blogs, 10)  # Show 10 blogs per page
        try:
            blogs = paginator.page(page)
        except PageNotAnInteger:
            blogs = paginator.page(1)
        except EmptyPage:
            blogs = paginator.page(paginator.num_pages)

        # Update template context
        context = super(BlogIndexPage, self).get_context(request)
        context['blogs'] = blogs
        return context
Beispiel #6
0
class ExternalArticlePage(Page, FeatureStyleFields, Promotable):
    body = RichTextField()
    website_link = models.URLField(max_length=255)
    main_image = models.ForeignKey(
        'images.AttributedImage',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+'
    )
    source = models.ForeignKey(
        'Source',
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+'
    )

    def __str__(self):
        return "{}".format(
            self.title
        )

    search_fields = Page.search_fields + (
        index.SearchField('body', partial_match=True),
        index.SearchField('source', partial_match=True),
    )

    def get_source_name(self):
        if self.source:
            return self.source.name
        else:
            return ""

    content_panels = Page.content_panels + [
        FieldPanel("body"),
        FieldPanel("website_link"),
        SnippetChooserPanel('source', Source),
        ImageChooserPanel('main_image'),
    ]
Beispiel #7
0
class ArtistIndexPage(Page):
    intro = RichTextField(blank=True)

    content_panels = Page.content_panels + [
        FieldPanel('intro', classname="full"),
    ]

    subpage_types = [ArtistProfilePage]

    @property
    def artists(self):
        artists = ArtistProfilePage.objects.live().descendant_of(self)

        artists = artists.order_by('last_name')

        return artists

    def get_context(self, request):
        # Get blogs
        artists = self.artists

        # Filter by tag
        tag = request.GET.get('tag')
        if tag:
            artists = artists.filter(tags__name=tag)

        # Pagination
        page = request.GET.get('page')
        paginator = Paginator(artists, 10)  # Show 10 blogs per page
        try:
            artists = paginator.page(page)
        except PageNotAnInteger:
            artists = paginator.page(1)
        except EmptyPage:
            artists = paginator.page(paginator.num_pages)

        # Update template context
        context = super(ArtistIndexPage, self).get_context(request)
        context['artists'] = artists
        return context
Beispiel #8
0
class ProductIndexPage(Page):
    subtitle = models.CharField(max_length=255, blank=True)
    intro = RichTextField(blank=True)

    indexed_fields = ('intro', )

    @property
    def products(self):
        # Get list of live blog pages that are descendants of this page
        products = ProductPage.objects.live().descendant_of(self)

        return products

    @property
    def tag_list(self):
        tag_ids = ProductPageTag.objects.all().values_list('tag_id', flat=True)
        return Tag.objects.filter(pk__in=tag_ids)

    def get_context(self, request):
        # Get products
        products = self.products
        # Filter by tag
        tag = request.GET.get('tag')
        if tag:
            products = products.filter(tags__name=tag)

        # Pagination
        page = request.GET.get('page')
        paginator = Paginator(products, 12)  # Show 10 products per page
        try:
            products = paginator.page(page)
        except PageNotAnInteger:
            products = paginator.page(1)
        except EmptyPage:
            products = paginator.page(paginator.num_pages)

        # Update template context
        context = super(ProductIndexPage, self).get_context(request)
        context['products'] = products
        return context
Beispiel #9
0
class ClubPage(Parent):
    body = RichTextField(blank=True)
    introduction = RichTextField(blank=True)
    values = RichTextField(blank=True)
    contact = RichTextField(blank=True)
    personnel = RichTextField(blank=True)
    partners = RichTextField(blank=True)

    content_panels = Page.content_panels + [
        FieldPanel('body', classname="full"),
        FieldPanel('introduction', classname="full"),
        FieldPanel('values', classname="full"),
        FieldPanel('contact', classname="full"),
        FieldPanel('personnel', classname="full"),
        FieldPanel('partners', classname="full"),
    ]
Beispiel #10
0
class BlogIndexPage(Page):
    page_ptr = models.OneToOneField(Page, parent_link=True, related_name='+')
    intro = RichTextField(blank=True)

    api_fields = (
        'intro',
        'related_links',
    )

    search_fields = Page.search_fields + [
        index.SearchField('intro'),
    ]

    def get_blog_entries(self):
        # Get list of live blog pages that are descendants of this page
        entries = BlogEntryPage.objects.descendant_of(self).live()

        # Order by most recent date first
        entries = entries.order_by('-date')

        return entries

    def get_context(self, request):
        # Get blog entries
        entries = self.get_blog_entries()

        # Filter by tag
        tag = request.GET.get('tag')
        if tag:
            entries = entries.filter(tags__name=tag)

        paginator, entries = paginate(request,
                                      entries,
                                      page_key='page',
                                      per_page=10)

        # Update template context
        context = super(BlogIndexPage, self).get_context(request)
        context['entries'] = entries
        return context
Beispiel #11
0
class BlogPage(Page):
    main_image = models.ForeignKey('wagtailimages.Image',
                                   null=True,
                                   blank=True,
                                   on_delete=models.SET_NULL,
                                   related_name='+')

    date = models.DateField("Post date")
    intro = models.CharField(max_length=250)
    body = RichTextField(blank=True)

    search_fields = Page.search_fields + [
        index.SearchField('intro'),
        index.SearchField('body'),
    ]

    content_panels = Page.content_panels + [
        FieldPanel('date'),
        ImageChooserPanel('main_image'),
        FieldPanel('intro'),
        FieldPanel('body', classname="full")
    ]
class ProductPage(Page):
    price = models.CharField(max_length=255, blank=True)
    description = RichTextField(blank=True)
    intro = models.CharField(max_length=255, blank=True)
    link_demo = models.URLField("Demo link", blank=True)
    tags = ClusterTaggableManager(through=ProductPageTag, blank=True)
    image = models.ForeignKey(
        Image,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+'
    )
    feed_image = models.ForeignKey(
        Image,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+'
    )

    indexed_fields = ('title', 'intro', 'biography')
Beispiel #13
0
class FabricationProjectPage(Page):    
    list_image = models.ForeignKey(
        'wagtailimages.Image', on_delete=models.PROTECT, related_name='+',
        blank=True, null=True, help_text="Minimum 800px wide & 800px tall"
    )
    
    description = RichTextField(features=['bold', 'italic', 'ul', 'ol', 'link'])
    items = models.CharField(blank=True, max_length=250)

    content_panels = Page.content_panels + [
        
        ImageChooserPanel('list_image'),
        FieldPanel('description'),
        FieldPanel('items'),
        InlinePanel('fabrication_project_gallery_images', label="Slideshow images"),
    ]

    subpage_types = []
    parent_page_types = ['fabrication.FabricationMaterialPage']

    class Meta:
        verbose_name = "Fabrication Project"
Beispiel #14
0
class DashboardSettings(BaseSetting):
    """Editable settings for the dashboard page."""

    category_preferences_header_text = models.CharField(
        max_length=100,
        help_text=
        "The heading of category preferences section in the 'My Impact' section of the dashboard.",
        default=
        'What type of projects should we invest your repayments in next?')

    category_preferences_explanation_header_text = models.CharField(
        max_length=50,
        help_text=
        "The header of the category preference explanation in the 'My Impact' section of the dashboard.",
        default="What's going on?")

    category_preferences_explanation_paragraph = RichTextField(
        help_text=
        "A paragraph which will appear below the category preference options on the 'My Impact' section on the dashboard to explain to the user what category preferences mean.",
        default=
        "<p>Your donation to RE-volv has been invested in a revolving fund. Money from the fund is used to place solar equipment on community buildings. Over time, the community pays RE-volv back. These repayments are invested in even more solar projects. A fraction of the repayments from a solar investment originates from your investment. Your preferences directly affect where that chunk of money is invested.</p>"
    )
Beispiel #15
0
class AchievementsPage(Page):
    date = models.DateField("Post date")

    competition_intro = models.CharField("About the Achievement",
                                         max_length=600)

    description = RichTextField("Decription")

    carousel = StreamField([
        ('image', ImageChooserBlock()),
        ('video', EmbedBlock()),
    ],
                           blank=True)

    content_panels = Page.content_panels + [
        FieldPanel('date'),
        FieldPanel('competition_intro'),
        FieldPanel('description', classname="full"),
        StreamFieldPanel('carousel'),
    ]

    parent_page_types = ['achievements.AchievementsIndexPage']
Beispiel #16
0
class HomePage(Page):
    parent_page_types = []

    body = RichTextField(blank=True)
    featured_article = models.ForeignKey(ArticlePage,
                                         null=True,
                                         blank=True,
                                         on_delete=models.SET_NULL)

    content_panels = Page.content_panels + [
        FieldPanel('body', classname="full"),
        PageChooserPanel('featured_article'),
        InlinePanel('preview_articles', label='Previewed Articles'),
    ]

    class Meta:
        verbose_name = "Homepage"

    def latest_articles(self):
        articles = ArticlePage.objects.live()
        articles = articles.order_by('-date')
        return articles[0:5]
class MarketplaceEntryPage(Page, ContactFields, TopImage):
    biography = RichTextField()
    date_start = models.DateField("Company Start Date")
    logo_image = models.ForeignKey(
        Image,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
    )

    class Meta:
        verbose_name = "marketplace"
        verbose_name_plural = "marketplace"

    @property
    def marketplace_index(self):
        # Find closest ancestor which is a marketplace index
        return self.get_ancestors().type(MarketplaceIndexPage).last()

    @property
    def name(self):
        return self.title
Beispiel #18
0
class Testimonial(LinkFields):
    page = models.ForeignKey(Page,
                             related_name='testimonials',
                             null=True,
                             blank=True)
    name = models.CharField(max_length=150)
    photo = models.ForeignKey(Image,
                              null=True,
                              blank=True,
                              on_delete=models.SET_NULL)
    text = RichTextField(blank=True)

    panels = [
        PageChooserPanel('page'),
        FieldPanel('name'),
        ImageChooserPanel('photo'),
        FieldPanel('text'),
        MultiFieldPanel(LinkFields.panels, "Link"),
    ]

    def __unicode__(self):
        return self.name
Beispiel #19
0
class BlogIndexPage(Page):
    intro = RichTextField(blank=True)

    indexed_fields = ('intro', )
    search_name = "Blog"

    @property
    def blogs(self):
        # Get list of blog pages that are descendants of this page
        blogs = BlogPage.objects.filter(live=True, path__startswith=self.path)

        # Order by most recent date first
        blogs = blogs.order_by('-date')

        return blogs

    def serve(self, request):
        # Get blogs
        blogs = self.blogs

        # Filter by tag
        tag = request.GET.get('tag')
        if tag:
            blogs = blogs.filter(tags__name=tag)

        # Pagination
        page = request.GET.get('page')
        paginator = Paginator(blogs, 10)  # Show 10 blogs per page
        try:
            blogs = paginator.page(page)
        except PageNotAnInteger:
            blogs = paginator.page(1)
        except EmptyPage:
            blogs = paginator.page(paginator.num_pages)

        return render(request, self.template, {
            'self': self,
            'blogs': blogs,
        })
Beispiel #20
0
class MoviePage(Page):
    """
    Movie Page
    A page of a movie's details
    """
    description = RichTextField(blank=True)
    genres = ParentalManyToManyField('catalog.MovieGenre', blank=True)

    def main_image(self):
        movie_item = self.movie_images.first()
        if movie_item:
            return movie_item.image
        else:
            return None

    content_panels = Page.content_panels + [
        MultiFieldPanel([
            FieldPanel('genres', widget=forms.CheckboxSelectMultiple),
        ]),
        FieldPanel('description'),
        InlinePanel('movie_images', label='Movie Images'),
    ]
Beispiel #21
0
class EventIndexPage(Page):
    intro = RichTextField(blank=True)

    search_fields = Page.search_fields + [
        index.SearchField('intro'),
    ]

    api_fields = ['intro', 'related_links']

    @property
    def events(self):
        # Get list of live event pages that are descendants of this page
        events = EventPage.objects.live().descendant_of(self)

        # Filter events list to get ones that are either
        # running now or start in the future
        events = events.filter(date_from__gte=date.today())

        # Order by date
        events = events.order_by('date_from')

        return events
Beispiel #22
0
class BlogPage(Page):
    date = models.DateField("Post date")
    intro = models.CharField(max_length=255)
    body = RichTextField(blank=True)
    blogElement = StreamField([
        ('heading', blocks.CharBlock(classname="full title")),
        ('paragraph', blocks.TextBlock()),
        ('picture', ImageChooserBlock()),
    ],
                              default=[])

    search_fields = Page.search_fields + [
        index.SearchField('intro'),
        index.SearchField('body'),
    ]

    content_panels = Page.content_panels + [
        FieldPanel('date'),
        FieldPanel('intro'),
        FieldPanel('body', classname="full"),
        StreamFieldPanel('blogElement'),
    ]
Beispiel #23
0
class EventPage(Page):
    date_from = models.DateField("Start date", null=True)
    date_to = models.DateField(
        "End date",
        null=True,
        blank=True,
        help_text="Not required if event is on a single day")
    time_from = models.TimeField("Start time", null=True, blank=True)
    time_to = models.TimeField("End time", null=True, blank=True)
    audience = models.CharField(max_length=255, choices=EVENT_AUDIENCE_CHOICES)
    location = models.CharField(max_length=255)
    body = RichTextField(blank=True)
    cost = models.CharField(max_length=255)
    signup_link = models.URLField(blank=True)
    feed_image = models.ForeignKey('wagtailimages.Image',
                                   null=True,
                                   blank=True,
                                   on_delete=models.SET_NULL,
                                   related_name='+')

    indexed_fields = ('get_audience_display', 'location', 'body')
    search_name = "Event"
Beispiel #24
0
class BlogPage(Page):
    author = models.ForeignKey(settings.AUTH_USER_MODEL,
                               null=True,
                               blank=True,
                               on_delete=models.SET_NULL)
    body = RichTextField(blank=True, editor='tinymce')
    date = models.DateField("Post date")
    intro = models.CharField(max_length=250)

    search_fields = Page.search_fields + [
        index.SearchField('intro'),
        index.SearchField('body'),
    ]

    parent_page_types = ['BlogIndexPage']

    content_panels = Page.content_panels + [
        FieldPanel('author'),
        FieldPanel('date'),
        FieldPanel('intro'),
        FieldPanel('body', classname="full"),
    ]
Beispiel #25
0
class BlogPage(Page):
    date = models.DateField("Post date")
    intro = models.CharField(max_length=250)
    body = RichTextField(blank=True)

    def main_image(self):
        gallery_item = self.gallery_images.first()
        if gallery_item:
            return gallery_item.image
        else:
            return None

    search_fields = Page.search_fields + [
        index.SearchField('intro'),
        index.SearchField('body'),
    ]

    content_panels = Page.content_panels + [
        FieldPanel('date'),
        FieldPanel('intro'),
        FieldPanel('body', classname="full"),
    ]
Beispiel #26
0
class NewsletterExternalArticleLink(Orderable, models.Model):
    external_article = models.ForeignKey(
        "articles.ExternalArticlePage",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name='+',
        help_text="Link to an external article")
    override_text = RichTextField(blank=True,
                                  default="",
                                  help_text="Text to describe article.")

    newsletter = ParentalKey("NewsletterPage",
                             related_name='external_article_links')

    def __str__(self):
        return "{}".format(self.external_article.title)

    panels = [
        PageChooserPanel("external_article", 'articles.ExternalArticlePage'),
        FieldPanel("override_text"),
    ]
Beispiel #27
0
class StandardPage(Page, HeroImageFields, SocialFields, ListingFields):
    introduction = RichTextField(
        blank=True, null=True, features=['bold', 'italic', 'link', 'justify'])
    body = StreamField(StandardPageBlock())
    call_to_action = models.ForeignKey('utils.CallToActionSnippet',
                                       null=True,
                                       blank=True,
                                       on_delete=models.SET_NULL,
                                       related_name='+')

    search_fields = Page.search_fields + HeroImageFields.search_fields + [
        index.SearchField('introduction'),
        index.SearchField('body'),
    ]

    content_panels = Page.content_panels + HeroImageFields.content_panels + [
        FieldPanel('introduction'),
        StreamFieldPanel('body'),
        SnippetChooserPanel('call_to_action'),
    ]

    promote_panels = Page.promote_panels + SocialFields.promote_panels + ListingFields.promote_panels
class Advert(LinkFields):
    page = models.ForeignKey(Page,
                             related_name='adverts',
                             null=True,
                             blank=True)
    title = models.CharField(max_length=150, null=True)
    image = models.ForeignKey(Image,
                              null=True,
                              blank=True,
                              on_delete=models.SET_NULL)
    text = RichTextField(blank=True)

    panels = [
        PageChooserPanel('page'),
        FieldPanel('title'),
        ImageChooserPanel('image'),
        FieldPanel('text'),
        MultiFieldPanel(LinkFields.panels, "Link"),
    ]

    def __unicode__(self):
        return self.title
Beispiel #29
0
class EventIndexPage(Page):
    intro = RichTextField(blank=True)

    search_fields = Page.search_fields + (index.SearchField('intro'), )

    class Meta:
        verbose_name_plural = 'Indices de Eventos'
        verbose_name = 'Indice de Eventos'

    @property
    def events(self):
        # Get list of live event pages that are descendants of this page
        events = EventPage.objects.live().descendant_of(self)

        # Filter events list to get ones that are either
        # running now or start in the future
        events = events.filter(date_from__gte=date.today())

        # Order by date
        events = events.order_by('date_from')

        return events
Beispiel #30
0
class HomePage(CustomPage):
    logo_image = models.ForeignKey(
        "wagtailimages.Image",
        blank=True,
        null=True,
        help_text="Maximum file size is 10 MB",
        on_delete=models.SET_NULL,
        related_name="+"
    )
    background_image = models.ForeignKey(
        "wagtailimages.Image",
        blank=True,
        null=True,
        help_text="Maximum file size is 10 MB",
        on_delete=models.SET_NULL,
        related_name="+"
    )
    conference_info_section = StreamField(HTMLBlock())
    pydata_info_section = StreamField(HTMLBlock())
    ticketing_section = RichTextField(default="<h2>Tickets</h2>")
    ticketing_url = models.URLField(blank=True, max_length=2083)
    mailchimp_list_id = models.CharField(blank=True, max_length=100)
    footer_email = models.EmailField(
        blank=True, default="*****@*****.**", max_length=254)
    footer_twitter = models.CharField(
        blank=True, default="PyData", max_length=15)

    content_panels = Page.content_panels + [
        FieldPanel("logo_image"),
        FieldPanel("background_image"),
        StreamFieldPanel("conference_info_section"),
        StreamFieldPanel("pydata_info_section"),
        FieldPanel("ticketing_section"),
        FieldPanel("ticketing_url"),
        FieldPanel("mailchimp_list_id"),
        FieldPanel("footer_email"),
        FieldPanel("footer_twitter"),
    ]
    template = "homepage.html"