In Wagtail, is it possible to filter pages that show up within the PageChooserPanel page?
For example if I'm setting a link for a french page, I would only want to see pages marked as French. Something like the fake example below:
class MyPage(Page):
french_link = models.ForeignKey(
Page,
null=True,
blank=True,
related_name='+',
on_delete=models.SET_NULL
)
panels = [
# something like this that can
# limit the pages to only ones where lang equals fr
PageChooserPanel('french_link', filter=limit_by_lang),
]
def limit_by_lang(query):
return query.get(lang='fr')
Thanks.
Related
I am new to Wagtail and have just successfully installed my first site with a StreamField block:
class DefaultPage(Page):
author = models.CharField(max_length=255, blank=True, null=True)
date = models.DateField("Post date", blank=True, null=True)
body = StreamField([
('title', blocks.CharBlock(form_classname="full title")),
('paragraph', blocks.RichTextBlock()),
('image', ImageChooserBlock()),
], blank=True, null=True)
However, the admin panel for the streamfield does not render this as expected. I expected a black control panel with inline editing, per the official Wagtail site:
Instead I have a different "light" theme UI:
Am I looking at different features? Is there an update in the latest release not on the official site?
Yes, the design of StreamField was updated in Wagtail 2.7.
(The outdated screenshot has been flagged up, and should hopefully be fixed in the next release.)
I've been around the Internet the whole day reading about the following issue, in wagtail if I registered the following model for translation like this:
class RecipientsPage(Page):
intro = RichTextField(null=True, blank=True)
banner_image = models.ForeignKey(
"wagtailimages.Image",
on_delete=models.SET_NULL,
related_name="+",
null=True,
blank=False,
help_text=_("the Image shouldn't exceed ") + "1350 * 210",
)
content_panels = Page.content_panels + [
FieldPanel("intro"),
ImageChooserPanel("image"),
]
this is how I registered the model:
#register(RecipientsCountriesPage)
class RecipientsCountriesPage(TranslationOptions):
fields = ("intro",)
It causes a problem, because like this I'll have two slugs following the two titles (The original English one and the Arabic translated one), if I change the Arabic slug manually to equal the English one it'll work, but it's not efficient to do so for each page manually
I've read about the issue a lot like in here:
https://github.com/infoportugal/wagtail-modeltranslation/issues/195
I've found also the following question with no answer
How do you translate the slug value of a page?
I've also read that I can override some of the wagtail Page methods but without further explanation and I'm a bit lost, what's the best way to overcome this issue?
I did it using Django signals
#receiver(pre_save)
def set_arabic_slug_on_new_instance(sender, instance, **kwargs):
if isinstance(instance, Page):
instance.slug_ar = instance.slug_en
I have been using the AbstractLinkPage model from wagtailmenus in my site for a while now. I find it quite useful.
Source: wagtailmenus AbstractLinkPage model
My site is building cards from children pages and adds banner images from children pages automatically to these cards. Some of the children pages are LinkPages.
How can I extend the subclassed LinkPage (from AbstractLinkPage) to add a generic image which can be used as a card image?
I have added the field:
class LinkPage(AbstractLinkPage):
card_image = models.ForeignKey(
get_image_model_string(),
null=True,
blank=True,
related_name='+',
on_delete=models.SET_NULL,
)
content_panels = AbstractLinkPage.content_panels + [
ImageChooserPanel("card_image"),
]
However the image card_image field does not show in the admin interface.
Any help to move forward is appreciated.
Wagtailmenus uses it's own tabbed interface (in wagtailmenus.panels):
linkpage_tab = ObjectList(
linkpage_panels, heading=_("Settings"), classname="settings"
)
linkpage_edit_handler = TabbedInterface([linkpage_tab])
So what you have to do is to create a new ObjectList:
from wagtailmenus.panels import linkpage_panels
from wagtail.admin.edit_handlers import ObjectList, TabbedInterface
my_linkpage_tab = ObjectList(
linkpage_panels + [ImageChooserPanel("card_image")],
heading=_("Settings"), classname="settings"
)
.. and add it to your class:
class LinkPage(AbstractLinkPage):
[..]
edit_handler = TabbedInterface([my_linkpage_tab])
I have an EventPage model that defines a number of ParentalManyToManyFields (one for tags and one for Event Sponsors). When I copy one of these pages, the regular ForeignKey fields get copied, but the ParentalManyToManyFields don't.
Here's what the code looks like:
tags = ParentalManyToManyField('master_calendar.EventTag', blank=True)
series = models.ForeignKey(
'master_calendar.EventSeries2',
null=True,
blank=True,
related_name='events',
on_delete=models.SET_NULL
)
sponsors = ParentalManyToManyField(
'master_calendar.EventSponsor2',
related_name='events',
blank=True
)
The series field gets copied just fine, but tags and sponsors don't. Why might that be happening?
Some time ago I stopped using #register_snippet to decorate Snippets. This takes the Snippet out of the snippets section of admin.
Instead I used the wagtail_hooks.py to show the snippet directly in the left admin panel for user convenience. See below. This works nicely as the user can go directly to the snippet and you can also alter the displayed fields and ordering of fields - nice.
So in the below example I removed the line that says #register_snippet. What's the catch? The SnippetChooserPanel does not work! Later I was building a complex model and the SnippetChooserPanel did not work. I wasted quite a bit of time thinking the problem was in the complexity of my model. I want to save others' time!
wagtail_hooks.py:
from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register
from wagtail.wagtailsnippets.models import register_snippet
from demo.models import Advert
class AdvertAdmin(ModelAdmin):
model = Advert
modeladmin_register(AdvertAdmin)
Here is the snippet example from Wagtail: snippets
#register_snippet #<------- Source of issue (I removed this line!)
#python_2_unicode_compatible # provide equivalent __unicode__ and __str__ methods on Python 2
class Advert(models.Model):
url = models.URLField(null=True, blank=True)
text = models.CharField(max_length=255)
panels = [
FieldPanel('url'),
FieldPanel('text'),
]
def __str__(self):
return self.text
class BookPage(Page):
advert = models.ForeignKey(
'demo.Advert',
null=True,
blank=True,
on_delete=models.SET_NULL,
related_name='+'
)
content_panels = Page.content_panels + [
SnippetChooserPanel('advert'),
# ...
]
If you make your Snippets editable via modelAdmin you still need to apply the decorator #register_snippet. Otherwise the chooser panel route/view won't be available. This view is requested by the ajax request fired on SnippetChooser modal open. Missing #register snippet will trow a 404.
You can register menu items via construct_main_menu hook. You can use the same hook to remove exiting menu-items. If you do not want the 'Snippets' menu item remove it. In wagtail_hooks.py:
#hooks.register('construct_main_menu')
def hide_snippet(request, menu_items):
menu_items[:] = [item for item in menu_items if item.name != 'snippets']
The solution is always use #register_snippet decorator otherwise the SnippetChooserPanel doesn't work!
#register_snippet
#python_2_unicode_compatible
class Advert(models.Model):
url = models.URLField(null=True, blank=True)
text = models.CharField(max_length=255)
panels = [
FieldPanel('url'),
FieldPanel('text'),
]
def __str__(self):
return self.text