def test_nested_2(): nested = Fragment(children__bar='bar') f = Fragment(children__foo='foo', children__bar=nested).bind(request=None) assert f._is_bound assert f._bound_members.children._bound_members.bar._is_bound assert not nested._is_bound assert f.__html__() == 'foobar'
def __html__(self, *, render=None): a = setdefaults_path( Namespace(), self.a, children__text=self.display_name, attrs__href=self.url, _name='a', ) if self._active: setdefaults_path( a, attrs__class={self.active_class: True}, ) if self.url is None and a.tag == 'a': a.tag = None fragment = Fragment( children__a=a, tag=self.tag, template=self.template, attrs=self.attrs, _name='fragment', ) fragment = fragment.bind(parent=self) # need to do this here because otherwise the sub menu will get get double bind for name, item in items(self.sub_menu): assert name not in fragment.children fragment.children[name] = item return fragment.__html__()
def test_nested_attrs_lambda(): f = Fragment( tag='div', children__text__tag='div', children__text__children__text='foo', children__text__attrs__qwe=lambda fragment, **_: fragment.tag, ).bind(request=None) assert f.__html__() == '<div><div qwe="div">foo</div></div>'
def test_fragment__render__simple_cases(): assert format_html('{}', html.h1('foo').bind(parent=None)) == '<h1>foo</h1>' assert format_html('{}', Fragment(children__child='foo<foo>').bind( parent=None)) == 'foo<foo>' assert fragment__render(Fragment(include=False), {}) == ''
def test_attrs(): f = Fragment( children__foo='foo', tag='div', attrs__class__foo=True, attrs__style__foo='foo', attrs__qwe='qwe', ).bind(request=None) assert f.__html__() == '<div class="foo" qwe="qwe" style="foo: foo">foo</div>'
def test_warning_when_names_are_recalculated(capsys): page = Page(parts__foo=Fragment(_name='foo')) assert get_path_by_long_path(page) == {'parts/foo': ''} out, err = capsys.readouterr() assert out == '' set_declared_member(page, 'bar', Fragment(_name='bar')) assert get_path_by_long_path(page) == { 'parts/foo': '', 'bar': 'bar', } out, err = capsys.readouterr() assert out == '### A disturbance in the force... The namespace has been recalculated!\n'
def test_assets_render_any_fragment_from_style(): register_style( 'my_style', Style( test, assets__an_asset=Fragment('This is a fragment!'), )) class MyPage(Page): class Meta: iommi_style = 'my_style' expected = prettify(''' <!DOCTYPE html> <html> <head> <title/> This is a fragment! </head> <body/> </html> ''') actual = prettify( MyPage().bind(request=req('get')).render_to_response().content) assert actual == expected unregister_style('my_style')
class RoomPage(Page): @reinvokable def __init__( self, room, unread_data, **kwargs ): self.room = room self.unread_data = unread_data super(RoomPage, self).__init__(**kwargs) header = Fragment(template='forum/room-header.html') table = Messages() hr = html.hr() refresh = html.script( 'start_subscription_refresh_subpage();', include=lambda request, **_: request.user_agent.is_mobile, ) def own_evaluate_parameters(self): return dict( page=self, room=self.room, unread_data=self.unread_data, unread_identifier=self.unread_data.unread_identifier, title=self.room.name, time=self.unread_data.unread2_time or self.unread_data.user_time, # TODO: handle this in UnreadData? is_subscribed=is_subscribed, )
def __html__(self, *, render=None): fragment = Fragment( _name=self._name, tag=self.tag, template=self.template, children__items_container=Fragment(**self.items_container, )).bind( parent=self) # need to do this here because otherwise the sub menu will get get double bind items_container = fragment.children.items_container for name, item in items(self.sub_menu): assert name not in items_container.children items_container.children[name] = item # If we pass attrs to the fragment in on_bind, styling can't be applied, so we do this thing instead. fragment.attrs = self.attrs return fragment.__html__()
def __html__(self): if not self: return '' from iommi import Fragment # We want the style system to treat this fragment like it's Errors, and # since it matches on the name of the class, inheritance here is enough class Errors(Fragment): pass # noinspection PyProtectedMember return (Errors( _name='error', tag='ul', attrs=self.attrs, template=self.template, children={ f'error_{i}': Fragment( tag='li', children__text=error, ) for i, error in enumerate(sorted(self._parent._errors)) }, ).bind(parent=self._parent).__html__())
def on_bind(self): super(Menu, self).on_bind() self.fragment = Fragment( _name=self._name, tag=self.tag, template=self.template, attrs=self.attrs, children__items_container=Fragment(**self.items_container, )).bind( parent=self) # need to do this here because otherwise the sub menu will get get double bind items_container = self.fragment.children.items_container for name, item in items(self.sub_menu): assert name not in items_container.children items_container.children[name] = item self.set_active(current_path=self.get_request().path)
def test_apply_style_not_affecting_definition(settings): register_style('my_style', Style(Fragment__attrs__class__foo=True, )) register_style('other_style', Style(Fragment__attrs__class__bar=True, )) definition = Fragment() settings.IOMMI_DEFAULT_STYLE = 'my_style' fragment = definition.bind(request=None) assert fragment.attrs['class'] == dict(foo=True) settings.IOMMI_DEFAULT_STYLE = 'other_style' fragment = definition.bind(request=None) assert fragment.attrs['class'] == dict(bar=True) unregister_style('my_style') unregister_style('other_style')
def __html__(self): if not self: return '' from iommi import Fragment return Fragment( _name='error', tag='ul', attrs=self.attrs, template=self.template, children={ f'error_{i}': Fragment( tag='li', children__text=error, ) for i, error in enumerate(sorted(self)) }, ).bind(parent=self._parent).__html__()
class ErrorMessages(Page): bind = Fragment() iommi_style = Fragment() iommi_path = Fragment() iommi_dunderpath = Fragment() on_bind = Fragment() own_evaluate_parameters = Fragment() get_request = Fragment()
def on_bind(self) -> None: super().on_bind() ms = messages.get_messages(self.get_request()) if ms: self.children.update({ f'message{i}': Fragment( tag='div', text=f'{m}', ).bind(parent=self) for i, m in enumerate(ms) })
def test_auto_h_tag(): # Start at h1 assert Header().bind(request=None).tag == 'h1' # Nesting doesn't increase level assert Fragment( children__child=Fragment( children__child=Header(), ) ).bind(request=None).__html__() == '<h1></h1>' # A header on a level increases the level for the next header assert Fragment( children__child=Fragment( children__child=Header( children__child=Header( children__child='h2', ) ) ) ).bind(request=None).__html__() == '<h1><h2>h2</h2></h1>' # Sibling headers get the same level assert Fragment( children__child=Fragment( children__child=Header( children__child=Header( children__child='h2'), children__another=Header( children__child='another h2', ) ) ) ).bind(request=None).__html__() == '<h1><h2>h2</h2><h2>another h2</h2></h1>'
def example_links(examples): children = {} for i, example in enumerate(examples): n = i + 1 children[f'example_{n}'] = html.p( Action( display_name=f'Example {n}: {example.description}', attrs__href=f'example_{n}', ), html.br(), ) return Fragment(children=children)
class MyPage(Page): header = Fragment() some_form = Form(fields=Namespace(fisk=Field(), )) some_other_form = Form(fields=Namespace( fjomp=Field(), fisk=Field(), )) a_table = Table( model=TFoo, columns=Namespace( columns=Column(), fusk=Column(attr='b', filter__include=True), ), )
class Meta: iommi_style = None parts__menu__sub_menu = dict( home=MenuItem(url='/'), admin=MenuItem(url=lambda **_: reverse(ExampleAdmin.all_models)), change_password=MenuItem( url=lambda **_: reverse(Auth.change_password)), logout=MenuItem(url=lambda **_: reverse(Auth.logout)), ) parts__footer = Fragment( after=LAST, children=dict( hr=html.hr(), style=StyleSelector(title='Change iommi style'), ))
def test_void_element(): for tag in [ 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr', ]: assert Fragment(tag=tag).bind(request=None).__html__() == f'<{tag}>'
def test_tag(): f = Fragment(children__foo='foo', tag='div').bind(request=None) assert f.__html__() == '<div>foo</div>'
def test_fragment_repr(): assert ( repr(Fragment(tag='foo', attrs=Attrs(None, **{'foo-bar': 'baz'}))) == "<Fragment tag:foo attrs:{'class': Namespace(), 'style': Namespace(), 'foo-bar': 'baz'}>" )
def test_render_multiple_children(): f = Fragment(children__foo='foo', children__bar='bar').bind(request=None) assert f.__html__() == 'foobar'
class MyPage(Page): title = Fragment( tag='h1', children__text=lambda request, **_: request.GET['foo'], )
class MyPage(Page): title = Fragment( tag='h1', children__text='Supernaut', )
def test_basic_render(): f = Fragment(children__text='foo').bind(request=None) assert f.__html__() == 'foo'
def test_fragment_with_two_children(): assert (Fragment(children__child='foo', tag='h1', children__foo='asd').bind( request=None).__html__() == '<h1>fooasd</h1>')
def test_fragment_with_tag(): assert Fragment(children__child='foo', tag='h1').bind(request=None).__html__() == '<h1>foo</h1>'
def test_fragment_basic(): assert Fragment(children__child='foo').bind( request=None).__html__() == 'foo'
def test_default_text(): assert Fragment('foo').bind(request=None).__html__() == 'foo'