return [ [ elist.as_data() if elist is not None else elist for elist in error.block_errors ], error.non_block_errors.as_data(), ] @cached_property def media(self): return forms.Media(js=[ versioned_static('wagtailadmin/js/telepath/blocks.js'), ]) register(ListBlockValidationErrorAdapter(), ListBlockValidationError) class ListBlock(Block): def __init__(self, child_block, **kwargs): super().__init__(**kwargs) if isinstance(child_block, type): # child_block was passed as a class, so convert it to a block instance self.child_block = child_block() else: self.child_block = child_block if not hasattr(self.meta, 'default'): # Default to a list consisting of one empty (i.e. default-valued) child item self.meta.default = [self.child_block.get_default()]
"embed_url": embed_url, "embed_id": embed_id, "lookup_url": lookup_url, "OBJECT_PK_PARAM": OBJECT_PK_PARAM, } def render_js_init(self, id_, name, value): config = self.get_js_config(id_, name) return "create_instance_selector_widget({config});".format( config=json.dumps(config)) class InstanceSelectorAdapter(WidgetAdapter): js_constructor = "wagtailinstanceselector.widgets.InstanceSelector" def js_args(self, widget): return [ widget.render_html("__NAME__", widget.get_value_data(None), attrs={"id": "__ID__"}), widget.get_js_config("__ID__", "__NAME__"), ] class Media: js = [ "instance_selector/instance_selector_telepath.js", ] register(InstanceSelectorAdapter(), InstanceSelectorWidget)
widget.render('__NAME__', None, attrs={'id': '__ID__'}), widget.id_for_label('__ID__'), ] def get_media(self, widget): media = super().get_media(widget) return media + widget.media @cached_property def media(self): return forms.Media(js=[ versioned_static('wagtailadmin/js/telepath/widgets.js'), ]) register(WidgetAdapter(), forms.widgets.Input) register(WidgetAdapter(), forms.Textarea) register(WidgetAdapter(), forms.CheckboxSelectMultiple) class CheckboxInputAdapter(WidgetAdapter): js_constructor = 'wagtail.widgets.CheckboxInput' register(CheckboxInputAdapter(), forms.CheckboxInput) class RadioSelectAdapter(WidgetAdapter): js_constructor = 'wagtail.widgets.RadioSelect'
"true" if settings.WAGTAILMARKDOWN["autodownload_fontawesome"] else "false") return 'easymdeAttach("{0}", {1});'.format(id_, autodownload) return 'easymdeAttach("{0}");'.format(id_) @property def media(self): return forms.Media( css={ "all": ( "wagtailmarkdown/css/easymde.min.css", "wagtailmarkdown/css/easymde.tweaks.css", ) }, js=( "wagtailmarkdown/js/easymde.min.js", "wagtailmarkdown/js/easymde.attach.js", ), ) class MarkdownTextareaAdapter(WidgetAdapter): js_constructor = "wagtailmarkdown.widgets.MarkdownTextarea" class Media: js = ["wagtailmarkdown/js/markdown-textarea-adapter.js"] register(MarkdownTextareaAdapter(), MarkdownTextarea)
class CustomBlockWithoutExtractMethod(blocks.Block): class Meta: default = None if telepath: class CustomBlockWithoutExtractMethodAdapter(telepath.Adapter): js_constructor = 'CustomBlockWithoutExtractMethod' def js_args(self, block): return [] telepath.register(CustomBlockWithoutExtractMethodAdapter(), CustomBlockWithoutExtractMethod) class TestStreamBlock(blocks.StreamBlock): test_charblock = blocks.CharBlock(max_length=255) test_textblock = blocks.TextBlock(label=gettext_lazy("text block")) test_emailblock = blocks.EmailBlock() test_urlblock = blocks.URLBlock() test_richtextblock = blocks.RichTextBlock() test_rawhtmlblock = blocks.RawHTMLBlock() test_blockquoteblock = blocks.BlockQuoteBlock() test_structblock = TestStructBlock() test_listblock = blocks.ListBlock(blocks.TextBlock()) test_nestedstreamblock = TestNestedStreamBlock() test_customstructblock = CustomStructBlock() test_customblockwithoutextractmethod = CustomBlockWithoutExtractMethod()
@cached_property def media(self): return forms.Media(js=[ versioned_static("wagtailsnippets/js/snippet-chooser-modal.js"), versioned_static("wagtailsnippets/js/snippet-chooser.js"), ]) class SnippetChooserAdapter(WidgetAdapter): js_constructor = "wagtail.snippets.widgets.SnippetChooser" def js_args(self, widget): return [ widget.render_html("__NAME__", None, attrs={"id": "__ID__"}), widget.id_for_label("__ID__"), ] @cached_property def media(self): return forms.Media(js=[ versioned_static("wagtailsnippets/js/snippet-chooser-telepath.js"), ]) register(SnippetChooserAdapter(), AdminSnippetChooser) class SnippetListingButton(ListingButton): pass
}) def render_js_init(self, id_, name, value_data): value_data = value_data or {} return "createPageChooser({id}, {parent}, {options});".format( id=json.dumps(id_), parent=json.dumps(value_data.get('parent_id')), options=json.dumps(self.client_options), ) @property def media(self): return forms.Media(js=[ versioned_static('wagtailadmin/js/page-chooser-modal.js'), versioned_static('wagtailadmin/js/page-chooser.js'), ]) class PageChooserAdapter(WidgetAdapter): js_constructor = 'wagtail.widgets.PageChooser' def js_args(self, widget): return [ widget.render_html('__NAME__', None, attrs={'id': '__ID__'}), widget.id_for_label('__ID__'), widget.client_options, ] register(PageChooserAdapter(), AdminPageChooser)
from django.forms import widgets from wagtail.core.telepath import register from wagtail.core.widget_adapters import WidgetAdapter class AdminAutoHeightTextInput(widgets.Textarea): template_name = "wagtailadmin/widgets/auto_height_text_input.html" def __init__(self, attrs=None): # Use more appropriate rows default, given autoheight will alter this anyway default_attrs = {"rows": "1"} if attrs: default_attrs.update(attrs) super().__init__(default_attrs) class AdminAutoHeightTextInputAdapter(WidgetAdapter): js_constructor = "wagtail.widgets.AdminAutoHeightTextInput" register(AdminAutoHeightTextInputAdapter(), AdminAutoHeightTextInput)
def media(self): return forms.Media(js=[ versioned_static('wagtailadmin/js/date-time-chooser.js'), ]) class AdminDateInputAdapter(WidgetAdapter): js_constructor = 'wagtail.widgets.AdminDateInput' def js_args(self, widget): return [ widget.get_config(), ] register(AdminDateInputAdapter(), AdminDateInput) class AdminTimeInput(widgets.TimeInput): template_name = 'wagtailadmin/widgets/time_input.html' def __init__(self, attrs=None, format=None): default_attrs = {'autocomplete': 'off'} if attrs: default_attrs.update(attrs) fmt = format if fmt is None: fmt = getattr(settings, 'WAGTAIL_TIME_FORMAT', DEFAULT_TIME_FORMAT) self.js_format = to_datetimepicker_format(fmt) super().__init__(attrs=default_attrs, format=fmt)
class StaticBlockAdapter(Adapter): js_constructor = "wagtail.blocks.StaticBlock" def js_args(self, block): admin_text = block.get_admin_text() if isinstance(admin_text, SafeString): text_or_html = "html" else: text_or_html = "text" return [ block.name, { text_or_html: admin_text, "icon": block.meta.icon, "label": block.label, }, ] @cached_property def media(self): return forms.Media(js=[ versioned_static("wagtailadmin/js/telepath/blocks.js"), ]) register(StaticBlockAdapter(), StaticBlock)
return context def value_from_datadict(self, data, files, name): original_value = super().value_from_datadict(data, files, name) if original_value is None: return None return self.converter.to_database_format(original_value) @cached_property def media(self): media = Media( js=[ versioned_static('wagtailadmin/js/vendor/hallo.js'), versioned_static('wagtailadmin/js/hallo-bootstrap.js'), ], css={ 'all': [versioned_static('wagtailadmin/css/panels/hallo.css')] }) for plugin in self.plugins: media += plugin.media return media class HalloRichTextAreaAdapter(WidgetAdapter): js_constructor = 'wagtail.widgets.HalloRichTextArea' register(HalloRichTextAreaAdapter(), HalloRichTextArea)
class ChartInputAdapter(WidgetAdapter): # This attribute is not strictly a Python path, but a namespace to look up a # matching JS constructor within Telepath. The JS constructor is registered in # bc/static_src/javascript/bc_admin_ui.js js_constructor = "bc.utils.widgets.ChartInput" class Media: js = ["js/bc_admin_ui.js"] css = {"all": ["bc_admin_ui/editor.css"]} def js_args(self, widget): return [widget.table_options, widget.chart_type] register(ChartInputAdapter(), BarChartInput) register(ChartInputAdapter(), PieChartInput) register(ChartInputAdapter(), LineChartInput) class CustomCheckboxSelectMultiple(forms.widgets.CheckboxSelectMultiple): template_name = ( "patterns/molecules/form-widgets/custom_checkbox_select_multiple.html") class CustomCheckboxSelectSingle(forms.widgets.CheckboxInput): template_name = "patterns/molecules/form-widgets/custom_checkbox_select_single.html" class TelephoneNumberInput(forms.widgets.TextInput): input_type = "tel"
class Album: def __init__(self, title, artists): self.title = title self.artists = artists class ArtistAdapter(Adapter): js_constructor = 'music.Artist' def js_args(self, obj): return [obj.name] register(ArtistAdapter(), Artist) class AlbumAdapter(Adapter): js_constructor = 'music.Album' def js_args(self, obj): return [obj.title, obj.artists] class Media: js = ['music_player.js'] register(AlbumAdapter(), Album)
"Table caption": _("Table caption"), "A heading that identifies the overall topic of the table, and is useful for screen reader users": _("A heading that identifies the overall topic of the table, and is useful for screen reader users" ), "Table": _("Table"), } return [ widget.table_options, strings, ] register(TableInputAdapter(), TableInput) class TableBlock(FieldBlock): def __init__(self, required=True, help_text=None, table_options=None, **kwargs): """ CharField's 'label' and 'initial' parameters are not exposed, as Block handles that functionality natively (via 'label' and 'default') CharField's 'max_length' and 'min_length' parameters are not exposed as table data needs to have arbitrary length """
return [{ row_index: { col_index: cell_error for col_index, cell_error in row_errors.items() } for row_index, row_errors in error.cell_errors.items() }] @cached_property def media(self): return forms.Media(js=[ versioned_static('typed_table_block/js/typed_table_block.js'), ]) register(TypedTableBlockValidationErrorAdapter(), TypedTableBlockValidationError) class TypedTable: template = 'typed_table_block/typed_table_block.html' def __init__(self, columns, row_data): # a list of dicts, each with items 'block' (the block instance) and 'heading' self.columns = columns # a list of dicts, each with an item 'values' (the list of block values) self.row_data = row_data @property def rows(self): """
def get_form_state(self, value): return self.widget.get_value_data(value) def get_instance_selector_icon(self): instance_selector = registry.get_instance_selector(self.target_model) return instance_selector.get_widget_icon() def deconstruct(self): name, args, kwargs = super().deconstruct() if args: args = args[1:] # Remove the args target_model kwargs["target_model"] = self.target_model._meta.label_lower return name, args, kwargs class InstanceSelectorBlockAdapter(FieldBlockAdapter): def js_args(self, block): name, widget, meta = super().js_args(block) # Fix up the 'icon' item in meta so that it's a string that we can serialize, # rather than a lazy reference if callable(meta["icon"]): meta["icon"] = meta["icon"]() return [name, widget, meta] register(InstanceSelectorBlockAdapter(), InstanceSelectorBlock)
class AdminVideoChooser(AdminMediaChooser): media_type = "video" choose_one_text = _("Choose video") choose_another_text = _("Choose another video") link_to_chosen_text = _("Edit this video") class MediaChooserAdapter(WidgetAdapter): js_constructor = "wagtailmedia.MediaChooser" def js_args(self, widget): return [ widget.render_html("__NAME__", None, attrs={"id": "__ID__"}), widget.id_for_label("__ID__"), ] @cached_property def media(self): return forms.Media( js=[ versioned_static("wagtailmedia/js/media-chooser-telepath.js"), ] ) register(MediaChooserAdapter(), AdminMediaChooser) register(MediaChooserAdapter(), AdminAudioChooser) register(MediaChooserAdapter(), AdminVideoChooser)
if error.block_errors is None: return [None] else: return [{ name: error_list.as_data() for name, error_list in error.block_errors.items() }] @cached_property def media(self): return forms.Media(js=[ versioned_static("wagtailadmin/js/telepath/blocks.js"), ]) register(StructBlockValidationErrorAdapter(), StructBlockValidationError) class StructValue(collections.OrderedDict): """A class that generates a StructBlock value from provided sub-blocks""" def __init__(self, block, *args): super().__init__(*args) self.block = block def __html__(self): return self.block.render(self) def render_as_block(self, context=None): return self.block.render(self, context=context) @cached_property
@property def media(self): return forms.Media( js=[ versioned_static("wagtailimages/js/image-chooser-modal.js"), versioned_static("wagtailimages/js/image-chooser.js"), ] ) class ImageChooserAdapter(WidgetAdapter): js_constructor = "wagtail.images.widgets.ImageChooser" def js_args(self, widget): return [ widget.render_html("__NAME__", None, attrs={"id": "__ID__"}), widget.id_for_label("__ID__"), ] @cached_property def media(self): return forms.Media( js=[ versioned_static("wagtailimages/js/image-chooser-telepath.js"), ] ) register(ImageChooserAdapter(), AdminImageChooser)
return self.converter.to_database_format(original_value) @cached_property def media(self): media = Media( js=[ versioned_static("wagtailadmin/js/draftail.js"), ], css={ "all": [versioned_static("wagtailadmin/css/panels/draftail.css")] }, ) for plugin in self.plugins: media += plugin.media return media class DraftailRichTextAreaAdapter(WidgetAdapter): js_constructor = "wagtail.widgets.DraftailRichTextArea" def js_args(self, widget): return [ widget.options, ] register(DraftailRichTextAreaAdapter(), DraftailRichTextArea)
meta['helpText'] = block.field.help_text return [ block.name, block.field.widget, meta, ] @cached_property def media(self): return forms.Media(js=[ versioned_static('wagtailadmin/js/telepath/blocks.js'), ]) register(FieldBlockAdapter(), FieldBlock) class CharBlock(FieldBlock): def __init__(self, required=True, help_text=None, max_length=None, min_length=None, validators=(), **kwargs): # CharField's 'label' and 'initial' parameters are not exposed, as Block handles that functionality natively # (via 'label' and 'default') self.field = forms.CharField( required=required, help_text=help_text,
def modal_url(self): opts = self.target_model._meta kwargs = {'app_label': opts.app_label, 'model_name': opts.model_name} if self.filter_name: kwargs['filter_name'] = self.filter_name return reverse('model_chooser', kwargs=kwargs) def render_js_init(self, id_, name, value): return "wagtail.ui.ModelChooser.setupWagtailWidget({id}, {url});".format( id=json.dumps(id_), url=json.dumps(self.modal_url)) class ModelChooserAdapter(WidgetAdapter): js_constructor = 'wagtailmodelchooser.widgets.ModelChooser' def js_args(self, widget): return [ widget.render_html('__NAME__', None, attrs={'id': '__ID__'}), widget.modal_url, ] class Media: js = [ 'wagtailmodelchooser/js/model_chooser_telepath.js', ] register(ModelChooserAdapter(), AdminModelChooser)
}) def render_js_init(self, id_, name, value_data): return "createDocumentChooser({0});".format(json.dumps(id_)) @property def media(self): return forms.Media(js=[ versioned_static('wagtaildocs/js/document-chooser-modal.js'), versioned_static('wagtaildocs/js/document-chooser.js'), ]) class DocumentChooserAdapter(WidgetAdapter): js_constructor = 'wagtail.documents.widgets.DocumentChooser' def js_args(self, widget): return [ widget.render_html('__NAME__', None, attrs={'id': '__ID__'}), widget.id_for_label('__ID__'), ] @cached_property def media(self): return forms.Media(js=[ versioned_static('wagtaildocs/js/document-chooser-telepath.js'), ]) register(DocumentChooserAdapter(), AdminDocumentChooser)
"class": "color-input-widget__text-input", } attrs = attrs or {} attrs = {**default_attrs, **attrs} super().__init__(attrs=attrs) def render_js_init(self, id_, name, value): return "new ColorInputWidget({0});".format(json.dumps(id_)) class Media: css = { "all": [ "wagtail_color_panel/css/color-input-widget.css", ] } js = [ "wagtail_color_panel/js/color-input-widget.js", ] class ColorInputWidgetAdapter(WidgetAdapter): js_constructor = "wagtail_color_panel.widgets.ColorInput" class Media: js = [ "wagtail_color_panel/js/color-input-widget-telepath.js", ] register(ColorInputWidgetAdapter(), ColorInputWidget)
class WidgetAdapter(Adapter): js_constructor = 'wagtail.widgets.Widget' def js_args(self, widget): return [ widget.render('__NAME__', None, attrs={'id': '__ID__'}), widget.id_for_label('__ID__'), ] def get_media(self, widget): media = super().get_media(widget) return media + widget.media @cached_property def media(self): return forms.Media(js=[ versioned_static('wagtailadmin/js/telepath/widgets.js'), ]) register(WidgetAdapter(), forms.widgets.Input) register(WidgetAdapter(), forms.Textarea) register(WidgetAdapter(), forms.Select) class RadioSelectAdapter(WidgetAdapter): js_constructor = 'wagtail.widgets.RadioSelect' register(RadioSelectAdapter(), forms.RadioSelect)