# -*- coding: utf-8 -*- # Tests for the media handling on widgets and forms media_tests = r""" >>> from django.forms import TextInput, Media, TextInput, CharField, Form, MultiWidget >>> from django.conf import settings >>> ORIGINAL_MEDIA_URL = settings.MEDIA_URL >>> settings.MEDIA_URL = 'http://media.example.com/media/' # Check construction of media objects >>> m = Media(css={'all': ('path/to/css1','/path/to/css2')}, js=('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3')) >>> print m >>> class Foo: ... css = { ... 'all': ('path/to/css1','/path/to/css2') ... } ... js = ('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3') >>> m3 = Media(Foo) >>> print m3 >>> m3 = Media(Foo) >>> print m3 # A widget can exist without a media definition >>> class MyWidget(TextInput): ... pass >>> w = MyWidget() >>> print w.media ############################################################### # DSL Class-based media definitions ############################################################### # A widget can define media if it needs to. # Any absolute path will be preserved; relative paths are combined # with the value of settings.MEDIA_URL >>> class MyWidget1(TextInput): ... class Media: ... css = { ... 'all': ('path/to/css1','/path/to/css2') ... } ... js = ('/path/to/js1','http://media.other.com/path/to/js2','https://secure.other.com/path/to/js3') >>> w1 = MyWidget1() >>> print w1.media # Media objects can be interrogated by media type >>> print w1.media['css'] >>> print w1.media['js'] # Media objects can be combined. Any given media resource will appear only # once. Duplicated media definitions are ignored. >>> class MyWidget2(TextInput): ... class Media: ... css = { ... 'all': ('/path/to/css2','/path/to/css3') ... } ... js = ('/path/to/js1','/path/to/js4') >>> class MyWidget3(TextInput): ... class Media: ... css = { ... 'all': ('/path/to/css3','path/to/css1') ... } ... js = ('/path/to/js1','/path/to/js4') >>> w2 = MyWidget2() >>> w3 = MyWidget3() >>> print w1.media + w2.media + w3.media # Check that media addition hasn't affected the original objects >>> print w1.media ############################################################### # Property-based media definitions ############################################################### # Widget media can be defined as a property >>> class MyWidget4(TextInput): ... def _media(self): ... return Media(css={'all': ('/some/path',)}, js = ('/some/js',)) ... media = property(_media) >>> w4 = MyWidget4() >>> print w4.media # Media properties can reference the media of their parents >>> class MyWidget5(MyWidget4): ... def _media(self): ... return super(MyWidget5, self).media + Media(css={'all': ('/other/path',)}, js = ('/other/js',)) ... media = property(_media) >>> w5 = MyWidget5() >>> print w5.media # Media properties can reference the media of their parents, # even if the parent media was defined using a class >>> class MyWidget6(MyWidget1): ... def _media(self): ... return super(MyWidget6, self).media + Media(css={'all': ('/other/path',)}, js = ('/other/js',)) ... media = property(_media) >>> w6 = MyWidget6() >>> print w6.media ############################################################### # Inheritance of media ############################################################### # If a widget extends another but provides no media definition, it inherits the parent widget's media >>> class MyWidget7(MyWidget1): ... pass >>> w7 = MyWidget7() >>> print w7.media # If a widget extends another but defines media, it extends the parent widget's media by default >>> class MyWidget8(MyWidget1): ... class Media: ... css = { ... 'all': ('/path/to/css3','path/to/css1') ... } ... js = ('/path/to/js1','/path/to/js4') >>> w8 = MyWidget8() >>> print w8.media # If a widget extends another but defines media, it extends the parents widget's media, # even if the parent defined media using a property. >>> class MyWidget9(MyWidget4): ... class Media: ... css = { ... 'all': ('/other/path',) ... } ... js = ('/other/js',) >>> w9 = MyWidget9() >>> print w9.media # A widget can disable media inheritance by specifying 'extend=False' >>> class MyWidget10(MyWidget1): ... class Media: ... extend = False ... css = { ... 'all': ('/path/to/css3','path/to/css1') ... } ... js = ('/path/to/js1','/path/to/js4') >>> w10 = MyWidget10() >>> print w10.media # A widget can explicitly enable full media inheritance by specifying 'extend=True' >>> class MyWidget11(MyWidget1): ... class Media: ... extend = True ... css = { ... 'all': ('/path/to/css3','path/to/css1') ... } ... js = ('/path/to/js1','/path/to/js4') >>> w11 = MyWidget11() >>> print w11.media # A widget can enable inheritance of one media type by specifying extend as a tuple >>> class MyWidget12(MyWidget1): ... class Media: ... extend = ('css',) ... css = { ... 'all': ('/path/to/css3','path/to/css1') ... } ... js = ('/path/to/js1','/path/to/js4') >>> w12 = MyWidget12() >>> print w12.media ############################################################### # Multi-media handling for CSS ############################################################### # A widget can define CSS media for multiple output media types >>> class MultimediaWidget(TextInput): ... class Media: ... css = { ... 'screen, print': ('/file1','/file2'), ... 'screen': ('/file3',), ... 'print': ('/file4',) ... } ... js = ('/path/to/js1','/path/to/js4') >>> multimedia = MultimediaWidget() >>> print multimedia.media ############################################################### # Multiwidget media handling ############################################################### # MultiWidgets have a default media definition that gets all the # media from the component widgets >>> class MyMultiWidget(MultiWidget): ... def __init__(self, attrs=None): ... widgets = [MyWidget1, MyWidget2, MyWidget3] ... super(MyMultiWidget, self).__init__(widgets, attrs) >>> mymulti = MyMultiWidget() >>> print mymulti.media ############################################################### # Media processing for forms ############################################################### # You can ask a form for the media required by its widgets. >>> class MyForm(Form): ... field1 = CharField(max_length=20, widget=MyWidget1()) ... field2 = CharField(max_length=20, widget=MyWidget2()) >>> f1 = MyForm() >>> print f1.media # Form media can be combined to produce a single media definition. >>> class AnotherForm(Form): ... field3 = CharField(max_length=20, widget=MyWidget3()) >>> f2 = AnotherForm() >>> print f1.media + f2.media # Forms can also define media, following the same rules as widgets. >>> class FormWithMedia(Form): ... field1 = CharField(max_length=20, widget=MyWidget1()) ... field2 = CharField(max_length=20, widget=MyWidget2()) ... class Media: ... js = ('/some/form/javascript',) ... css = { ... 'all': ('/some/form/css',) ... } >>> f3 = FormWithMedia() >>> print f3.media # Media works in templates >>> from django.template import Template, Context >>> Template("{{ form.media.js }}{{ form.media.css }}").render(Context({'form': f3})) u' ' >>> settings.MEDIA_URL = ORIGINAL_MEDIA_URL """