New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Let developer specify a root page for a PageChooserPanel #3322
Comments
We encounter the very same issue. Another possibility is to use the on_instance_bound hook (https://stackoverflow.com/a/59905949): class InstanceAwareStreamFieldPanel(StreamFieldPanel):
def on_instance_bound(self):
if not self.form:
return
widget = self.form[self.field_name].field.widget
for _, child_block in widget.block_def.child_blocks.items():
self.recursive(child_block)
def recursive(self, block):
if hasattr(block, "widget") and isinstance(block.widget, AdminChildPageChooser):
block.widget = AdminChildPageChooser(
target_models=block.widget.target_models,
can_choose_root=block.widget.can_choose_root,
page_instance_id=self.instance.id,
)
if hasattr(block, "child_block"):
self.recursive(block.child_block)
if not hasattr(block, "child_blocks"):
return
for _, child_block in block.child_blocks.items():
self.recursive(child_block) Then extending the AdminPageChooser and the PageChooserBlock to render a different template: class AdminChildPageChooser(AdminPageChooser):
def __init__(self, **kwargs):
self.page_instance_id = kwargs.pop("page_instance_id", None)
super().__init__(**kwargs)
def render_html(self, name, value_data, attrs):
value_data = value_data or {}
return render_to_string(
"wagtailadmin/child_page_chooser.html",
{
"widget": self,
"original_field_html": "",
"attrs": attrs,
"value": bool(
value_data
), # only used by chooser.html to identify blank values
"display_title": value_data.get("display_title", ""),
"edit_url": value_data.get("edit_url", ""),
"page_instance_id": self.page_instance_id,
},
)
class ChildPageChooserBlock(blocks.PageChooserBlock):
def __init__(
self,
page_type=None,
can_choose_root=False,
target_model=None,
**kwargs,
):
self.page_instance_id = kwargs.pop("page_instance_id", None)
super().__init__(
page_type=page_type,
can_choose_root=can_choose_root,
target_model=target_model,
**kwargs,
)
@cached_property
def widget(self):
return AdminChildPageChooser(
target_models=self.target_models,
can_choose_root=self.can_choose_root,
page_instance_id=self.page_instance_id,
)
{% extends "wagtailadmin/widgets/chooser.html" %}
{% load wagtailadmin_tags %}
{% block unchosen_icon %}{% icon name="doc-empty-inverse" %}{% endblock unchosen_icon %}
{% block chosen_icon %}{% icon name="doc-empty-inverse" %}{% endblock chosen_icon %}
{% block chooser_attributes %}
{% if page_instance_id %}
data-chooser-url="{% url 'wagtailadmin_choose_page_child' page_instance_id %}"
{% else %}
data-chooser-url="{% url 'wagtailadmin_choose_page' %}"
{% endif %}
{% endblock %} The rendered html will be cached, so it only works for the first time. Long story short: We would really appreciate a clean api to set the root page for the PageChooser. |
We found a solution for our needs with https://github.com/wagtail/wagtail-generic-chooser. |
We have a situation where a client has a deep page structure with several similar departments, each with similar sub-pages. They want to make linking of specific sub-pages to the "department index" easier with a page chooser. That page chooser should be anchored to the current page and only show sub-pages of that page (still of a certain type).
It would be nice if we could specify the root page of a PageChooserPanel and set it to the current page dynamically.
The text was updated successfully, but these errors were encountered: