class TabBlock(StructBlock): name = CharBlock() content = GenericContentStreamBlock(local_blocks=[('columns', RowBlock())]) class Meta: form_template = 'common/block_forms/tab.html'
class Footer(Model): title = CharField(default='untitled', max_length=255) content = StreamField([ ('heading', blocks.CharBlock(classname="full title")), ('paragraph', RichTextBlock()), ('image', ImageChooserBlock()), ('columns', RowBlock()), ('raw_html', RawHTMLBlock( help_text= 'With great power comes great responsibility. This HTML is unescaped. Be careful!' )), ('google_map', GoogleMapBlock()), ('twitter_feed', TwitterBlock()), ('photo_stream', COSPhotoStreamBlock()), ('centered_text', CenteredTextBlock()), ], null=True, blank=True) class Meta: verbose_name = "Footer" verbose_name_plural = "Footers" panels = [ FieldPanel('title'), StreamFieldPanel('content'), ] def __str__(self): return self.title
class CustomPage(Page, index.Indexed): footer = ForeignKey('common.Footer', default=DEFAULT_FOOTER_ID, null=True, blank=True, on_delete=SET_NULL, related_name='+') content = StreamField([ ('appeal', StructBlock([ ('icon', ChoiceBlock(required=True, choices=[ ('none', 'none'), ('flask', 'flask'), ('group', 'group'), ('laptop', 'laptop'), ('sitemap', 'sitemap'), ('user', 'user'), ('book', 'book'), ('download', 'download'), ])), ('topic', CharBlock(required=True, max_length=35)), ('content', RichTextBlock(required=True)), ], classname='appeal', icon='tick', template='common/blocks/appeal.html')), ('heading', CharBlock(classname="full title")), ('statement', CharBlock()), ('paragraph', RichTextBlock()), ('imagechooser', ImageChooserBlock()), ('column', RowBlock()), ('tabs', TabsBlock()), ('image', ImageBlock()), ('customImage', CustomImageBlock()), ('rich_text', RichTextBlock()), ('raw_html', RawHTMLBlock( help_text= 'With great power comes great responsibility. This HTML is unescaped. Be careful!' )), ('people_block', PeopleBlock()), ('centered_text', CenteredTextBlock()), ('hero_block', HeroBlock()), ('spotlight_block', SpotlightBlock()), ('job_whole_block', JobsWholeBlock()), ('embed_block', EmbedBlock()), ('whitespaceblock', WhitespaceBlock()), ('clear_fixblock', ClearfixBlock()), ('code_block', CodeBlock()), ('table_block', CustomTableBlock()), ('calender_block', GoogleCalendarBlock()), ('journal_block', JournalsTabBlock()), ('render_file', MfrBlock()), ('sponsor_partner_block', SponsorPartnerBlock()), ('collapse_block', CollapseBoxBlock()), ('button', ButtonBlock()), ], null=True, blank=True) custom_url = CharField(max_length=256, default='', null=True, blank=True) menu_order = IntegerField( blank=True, default=1, help_text=( 'The order this page should appear in the menu. ' 'The lower the number, the more left the page will appear. ' 'This is required for all pages where "Show in menus" is checked.' )) search_fields = [ index.SearchField('content', partial_match=True), ] content_panels = Page.content_panels + [ StreamFieldPanel('content'), SnippetChooserPanel('footer'), ] promote_panels = Page.promote_panels + [ FieldPanel('custom_url'), FieldPanel('menu_order'), InlinePanel('versioned_redirects', label='URL Versioning'), ] def serve(self, request): return render( request, self.template, { 'page': self, 'people': Person.objects.all(), 'jobs': Job.objects.all(), 'journals': Journal.objects.all(), 'organizations': Organization.objects.all(), 'donations': Donation.objects.all(), 'inkinddonations': InkindDonation.objects.all(), }) @transaction.atomic # only commit when all descendants are properly updated def move(self, target, pos=None): """ Extension to the treebeard 'move' method to ensure that url_path is updated too. """ old_url_path = Page.objects.get(id=self.id).url_path super(Page, self).move(target, pos=pos) # treebeard's move method doesn't actually update the in-memory instance, so we need to work # with a freshly loaded one now new_self = Page.objects.get(id=self.id) new_url_path = new_self.set_url_path(new_self.get_parent()) new_self.save() new_self._update_descendant_url_paths(old_url_path, new_url_path) new_redirect = new_self.versioned_redirects.create() redirect_url = ('/' + '/'.join(old_url_path.split('/')[2:]))[:-1] new_redirect.old_path = redirect_url new_redirect.redirect_page = new_self new_redirect.site = new_self.get_site() new_redirect.save() new_self.redirect_set.add(new_redirect) # Log logger.info("Page moved: \"%s\" id=%d path=%s", self.title, self.id, new_url_path) @transaction.atomic # ensure that changes are only committed when we have updated all descendant URL paths, to preserve consistency def save(self, *args, **kwargs): self.full_clean() update_descendant_url_paths = False is_new = self.id is None if is_new: # we are creating a record. If we're doing things properly, this should happen # through a treebeard method like add_child, in which case the 'path' field # has been set and so we can safely call get_parent self.set_url_path(self.get_parent()) else: # Check that we are committing the slug to the database # Basically: If update_fields has been specified, and slug is not included, skip this step if not ('update_fields' in kwargs and 'slug' not in kwargs['update_fields']): # see if the slug has changed from the record in the db, in which case we need to # update url_path of self and all descendants old_record = Page.objects.get(id=self.id) if old_record.slug != self.slug: self.set_url_path(self.get_parent()) update_descendant_url_paths = True old_url_path = old_record.url_path new_url_path = self.url_path new_redirect = self.versioned_redirects.create() redirect_url = ('/' + '/'.join(old_url_path.split('/')[2:]))[:-1] new_redirect.old_path = redirect_url new_redirect.redirect_page = self new_redirect.site = self.get_site() new_redirect.save() self.redirect_set.add(new_redirect) for redirect in self.versioned_redirects.all(): redirect.versioned_redirect_page = self redirect.redirect_page = self redirect.save() result = super(Page, self).save(*args, **kwargs) if update_descendant_url_paths: self._update_descendant_url_paths(old_url_path, new_url_path) # Check if this is a root page of any sites and clear the 'wagtail_site_root_paths' key if so if Site.objects.filter(root_page=self).exists(): cache.delete('wagtail_site_root_paths') # Log if is_new: cls = type(self) logger.info( "Page created: \"%s\" id=%d content_type=%s.%s path=%s", self.title, self.id, cls._meta.app_label, cls.__name__, self.url_path) return result