wagtail/wagtail/contrib/styleguide/views.py

170 wiersze
6.1 KiB
Python

import itertools
import os
import re
from collections import defaultdict
from django import forms
from django.core.paginator import Paginator
from django.template.loader import render_to_string
from django.utils.translation import gettext as _
from django.views.generic.base import TemplateView
from wagtail import hooks
from wagtail.admin import messages
from wagtail.admin.forms.search import SearchForm
from wagtail.admin.rich_text import get_rich_text_editor_widget
from wagtail.admin.staticfiles import versioned_static
from wagtail.admin.views.generic import WagtailAdminTemplateMixin
from wagtail.admin.widgets import (
AdminAutoHeightTextInput,
AdminDateInput,
AdminDateTimeInput,
AdminPageChooser,
AdminTimeInput,
SwitchInput,
)
from wagtail.documents.widgets import AdminDocumentChooser
from wagtail.images.widgets import AdminImageChooser
from wagtail.models import Page
from wagtail.snippets.widgets import AdminSnippetChooser
class FakeAdminSnippetChooser(AdminSnippetChooser):
"""
AdminSnippetChooser can't be used on non-snippet models (because it fails when constructing the
URL to the chooser modal), and we can't guarantee that any given Wagtail installation using
this style guide will have any snippet models registered. We therefore override the
get_chooser_modal_url method so that we can use it with Page as a stand-in for a real snippet.
"""
def get_chooser_modal_url(self):
return "/"
class ExampleForm(forms.Form):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["page_chooser"].widget = AdminPageChooser()
self.fields["image_chooser"].widget = AdminImageChooser()
self.fields["document_chooser"].widget = AdminDocumentChooser()
self.fields["snippet_chooser"].widget = FakeAdminSnippetChooser(Page)
self.fields["date"].widget = AdminDateInput()
self.fields["time"].widget = AdminTimeInput()
self.fields["datetime"].widget = AdminDateTimeInput()
self.fields["auto_height_text"].widget = AdminAutoHeightTextInput()
self.fields["default_rich_text"].widget = get_rich_text_editor_widget("default")
self.fields["switch"].widget = SwitchInput()
self.fields["disabled_switch"].widget = SwitchInput(attrs={"disabled": True})
CHOICES = (
("choice1", "choice 1"),
("choice2", "choice 2 that is longer but pretty normal"),
(
"choice3",
"""
choice 3 that has a very long label that it cannot possibly fit within the
width of the parent container but we're going to test it anyway to see
what happens and how it wraps and whether it breaks the layout or not
""",
),
)
text = forms.CharField(required=True, help_text="help text")
auto_height_text = forms.CharField(required=True)
default_rich_text = forms.CharField(required=True)
url = forms.URLField(required=True)
email = forms.EmailField(max_length=254)
date = forms.DateField()
time = forms.TimeField()
datetime = forms.DateTimeField()
select = forms.ChoiceField(choices=CHOICES[:2])
long_select = forms.ChoiceField(choices=CHOICES)
radio_select = forms.ChoiceField(choices=CHOICES, widget=forms.RadioSelect)
multiple_select = forms.MultipleChoiceField(choices=CHOICES)
multiple_checkbox = forms.MultipleChoiceField(
choices=CHOICES, widget=forms.CheckboxSelectMultiple
)
boolean = forms.BooleanField(required=False)
switch = forms.BooleanField(required=False)
disabled_switch = forms.BooleanField(required=False)
page_chooser = forms.BooleanField(required=True)
image_chooser = forms.BooleanField(required=True)
document_chooser = forms.BooleanField(required=True)
snippet_chooser = forms.BooleanField(required=True)
@property
def media(self):
return super().media + forms.Media(
css={
"all": [versioned_static("wagtailstyleguide/css/animate-progress.css")]
}
)
icon_id_pattern = re.compile(r"id=\"icon-([a-z0-9-]+)\"")
icon_comment_pattern = re.compile(r"<!--!(.*?)-->")
class IndexView(WagtailAdminTemplateMixin, TemplateView):
template_name = "wagtailstyleguide/base.html"
page_title = _("Styleguide")
header_icon = "image"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
messages.success(
self.request,
_("Success message"),
buttons=[
messages.button("", _("View live")),
messages.button("", _("Edit")),
],
)
messages.warning(
self.request,
_("Warning message"),
buttons=[
messages.button("", _("View live")),
messages.button("", _("Edit")),
],
)
messages.error(
self.request,
_("Error message"),
buttons=[
messages.button("", _("View live")),
messages.button("", _("Edit")),
],
)
context["all_icons"] = self.get_icons()
context["example_form"] = ExampleForm()
context["example_page"] = Paginator(list(range(100)), 10).page(2)
context["search_form"] = SearchForm()
return context
def get_icons(self):
icon_hooks = hooks.get_hooks("register_icons")
registered_icons = itertools.chain.from_iterable(
hook([]) for hook in icon_hooks
)
all_icons = defaultdict(list)
for icon_path in registered_icons:
folder, filename = os.path.split(icon_path)
icon = render_to_string(icon_path)
id_match = icon_id_pattern.search(icon)
name = id_match.group(1) if id_match else None
source_match = icon_comment_pattern.search(icon)
all_icons[folder].append(
{
"folder": folder,
"file_path": icon_path,
"name": name,
"source": source_match.group(1) if source_match else None,
}
)
return all_icons.items()