class SubmitPage(Page): heading = html.h1('TriOptima URL Blessalizer') form = SubmitForm() set_focus = html.script( mark_safe('document.getElementById("id_url").focus();', )) admin = html.p(html.a('Admin', attrs__href='/entries'), ' (requires login)')
class AlbumPage(Page): title = html.h1(album) text = html.a(album.artist, attrs__href=album.artist.get_absolute_url()) tracks = TrackTable( auto__rows=Track.objects.filter(album=album), columns__album__include=False, )
class ExamplesPage(Page): menu = menu footer = html.div( html.hr(), html.a('iommi rocks!', attrs__href='http://iommi.rocks/'), StyleSelector(), after=LAST, )
class AdminPage(Page): admin_header = Header('Admin example') admin_a = html.p(html.a( 'Admin', attrs__href="iommi-admin/", ), ) log_in = html.a( 'Log in', attrs__href='/iommi-admin/login/?next=/', include=lambda request, **_: not request.user.is_authenticated, ) log_out = html.a( 'Log out', attrs__href='/iommi-admin/logout/', include=lambda request, **_: request.user.is_authenticated, )
class AdminPage(Page): admin_header = html.h2('Admin example') log_in = html.a( 'Log in', attrs__href='/log_in/', include=lambda request, **_: not request.user.is_authenticated, ) log_out = html.a( 'Log out', attrs__href='/log_out/', include=lambda request, **_: request.user.is_authenticated, ) admin_a = html.p( html.a( 'Admin (needs login)', attrs__href=lambda request, **_: "iommi-admin/" if request.user.is_authenticated else None, ), )
class LoginPage(Page): styling = html.style(""" .extra_links, .form { margin-left: auto; margin-right: auto; width: 710px; } """) form = LoginForm() links = html.div( attrs__class__extra_links=True, attrs__style={'text-align': 'right'}, children__create_account=html.a('Create account', attrs__href='/create-account/'), children__p=html.div(), children__forgot_passsword=html.a('Forgot your password?', attrs__href='/forgot-password/'), ) set_focus = html.script( mark_safe('document.getElementById("id_username").focus();'))
class IndexPage(Page): menu = SupernautMenu() title = html.h1(_('Supernaut')) welcome_text = html.div( _('This is a discography of the best acts in music!')) log_in = html.a( _('Log in'), attrs__href='/log_in/', include=lambda request, **_: not request.user.is_authenticated, ) log_out = html.a( _('Log out'), attrs__href='/log_out/', include=lambda request, **_: request.user.is_authenticated, ) albums = AlbumTable( auto__model=Album, tag='div', header__template=None, cell__tag=None, row__template=Template(""" <div class="card" style="width: 15rem; display: inline-block;" {{ cells.attrs }}> <img class="card-img-top" src="/static/album_art/{{ row.artist }}/{{ row.name|urlencode }}.jpg"> <div class="card-body text-center"> <h5>{{ cells.name }}</h5> <p class="card-text"> {{ cells.artist }} </p> </div> </div> """), )
class IndexPage(Page): header = Header('iommi examples') form_header = Header('Form examples') # We can create html fragments... f_a_1 = html.a('Example 1: echo submitted data', attrs__href="form_example_1/") f_b_1 = html.br() f_a_2 = html.a('Example 2: create a Foo', attrs__href="form_example_2/") f_b_2 = html.br() f_a_3 = html.a('Example 3: edit a Foo', attrs__href="form_example_3/") f_b_3 = html.br() f_a_4 = html.a('Example 4: custom buttons', attrs__href="form_example_4/") f_b_4 = html.br() f_a_5 = html.a('Example 5: automatic AJAX endpoint', attrs__href="form_example_5/") f_b_5 = html.br() f_a_k = html.a('Kitchen sink', attrs__href="form_kitchen/") table_header = Header('Table examples') # ...or just throw a big chunk of html in here table_links = mark_safe(""" <a href="table_readme_example_1/">Example 1 from the README</a><br> <a href="table_readme_example_2/">Example 2 from the README</a><br> <a href="table_auto_example_1/">Example 1 of auto table</a><br> <a href="table_auto_example_2/">Example 2 of auto table</a><br> <a href="table_kitchen_sink/">Kitchen sink</a><br> <a href="table_as_view/">Table.as_view() example</a><br> """) page_header = Header('Page examples') page_links = mark_safe(""" <a href="page_busy/">A busy page with lots of stuff</a><br> <a href="all_field_sorts">Show different type of form field types</a><br> <a href="all_column_sorts">Show different type of table column types</a> """) menu_header = Header('Menu examples') menu_examples = mark_safe(""" <a href="menu_test/">A menu example</a><br> """) # You can also nest pages admin = AdminPage() select_style = StyleSelector()
class IndexPage(Page): header = html.h1('iommi examples') form_header = html.h2('Form examples') # We can create html fragments... f_a_1 = html.a('Example 1: echo submitted data', attrs__href="form_example_1/") f_b_1 = html.br() f_a_2 = html.a('Example 2: create a Foo', attrs__href="form_example_2/") f_b_2 = html.br() f_a_3 = html.a('Example 3: edit a Foo', attrs__href="form_example_3/") f_b_3 = html.br() f_a_4 = html.a('Example 4: custom buttons', attrs__href="form_example_4/") f_b_4 = html.br() f_a_5 = html.a('Example 5: automatic AJAX endpoint', attrs__href="form_example_5/") f_b_5 = html.br() f_a_k = html.a('Kitchen sink', attrs__href="form_kitchen/") table_header = html.h2('Table examples') # ...or just throw a big chunk of html in here table_links = mark_safe(""" <a href="table_readme_example_1/">Example 1 from the README</a><br> <a href="table_readme_example_2/">Example 2 from the README</a><br> <a href="table_kitchen_sink/">Kitchen sink</a><br> """) page_header = html.h2('Page examples') page_links = mark_safe(""" <a href="page_busy/">A busy page with lots of stuff</a><br> """) # You can also nest pages admin = AdminPage()
class AdminPage(Page): admin_header = html.h2('Admin example') admin_a = html.a('Admin', attrs__href="iommi-admin/")
def test_render_simple_tag(): assert html.a('bar', attrs__href='foo').bind( parent=None).__html__() == '<a href="foo">bar</a>'
class Admin(Page): header = html.h1(children__link=html.a('Admin'))
class Admin(Page): link = html.a('Admin')
class Admin(Page): class Meta: table_class = Table form_class = Form apps__sessions_session__include = False parts__list_auth_user__columns__password__include = False table_class: Type[Table] = Refinable() form_class: Type[Form] = Refinable() apps: Namespace = Refinable() # Global configuration on apps level @reinvokable @dispatch( apps=EMPTY, parts=EMPTY, ) def __init__(self, parts, **kwargs): def should_throw_away(k, v): if isinstance(v, Namespace) and 'call_target' in v: return False if k == 'all_models': return True prefix_blacklist = [ 'list_', 'delete_', 'create_', 'edit_', ] for prefix in prefix_blacklist: if k.startswith(prefix): return True return False parts = { # Arguments that are not for us needs to be thrown on the ground k: None if should_throw_away(k, v) else v for k, v in items(parts) } super(Admin, self).__init__(parts=parts, **kwargs) @staticmethod def has_permission(request, operation, model=None, instance=None): return request.user.is_staff header = html.h1(children__link=html.a(children__text='Admin'), after=0) def own_evaluate_parameters(self): return dict(admin=self, **super(Admin, self).own_evaluate_parameters()) @classmethod @class_shortcut( table=EMPTY, ) def all_models(cls, request, table, call_target=None, **kwargs): if not cls.has_permission(request, operation='all_models'): raise Http404() def preprocess_rows(admin, rows, **_): return [ row for row in rows if admin.apps.get(f'{row.app_name}_{row.model_name}', {}).get('include', True) ] table = setdefaults_path( Namespace(), table, title='All models', call_target__cls=cls.get_meta().table_class, sortable=False, rows=[ Struct(app_name=app_name, model_name=model_name, model=model) for (app_name, model_name), model in items(model_by_app_and_name) ], preprocess_rows=preprocess_rows, columns=dict( app_name__auto_rowspan=True, app_name__after=0, model_name__cell__url=lambda row, **_: '%s/%s/' % (row.app_name, row.model_name), ), ) return call_target( parts__all_models=table, **kwargs ) @classmethod @class_shortcut( table=EMPTY, ) def list(cls, request, app_name, model_name, table, call_target=None, **kwargs): model = django_apps.all_models[app_name][model_name] if not cls.has_permission(request, operation='list', model=model): raise Http404() table = setdefaults_path( Namespace(), table, call_target__cls=cls.get_meta().table_class, auto__model=model, columns=dict( select__include=True, edit=dict( call_target__attribute='edit', after=0, cell__url=lambda row, **_: '%s/edit/' % row.pk, ), delete=dict( call_target__attribute='delete', after=LAST, cell__url=lambda row, **_: '%s/delete/' % row.pk, ), ), actions=dict( create=dict( display_name=f'Create {model._meta.verbose_name}', attrs__href='create/', ), ), query_from_indexes=True, bulk__actions__delete__include=True, **{ 'columns__' + field.name + '__bulk__include': True for field in get_fields(model) if not getattr(field, 'unique', False) }, ) return call_target( parts__header__children__link__attrs__href='../..', **{f'parts__list_{app_name}_{model_name}': table}, **kwargs, ) @classmethod @class_shortcut( form=EMPTY, ) def crud(cls, request, operation, form, app_name, model_name, pk=None, call_target=None, **kwargs): model = django_apps.all_models[app_name][model_name] instance = model.objects.get(pk=pk) if pk is not None else None if not cls.has_permission(request, operation=operation, model=model, instance=instance): raise Http404() form = setdefaults_path( Namespace(), form, call_target__cls=cls.get_meta().form_class, auto__instance=instance, auto__model=model, call_target__attribute=operation, ) return call_target( **{f'parts__{operation}_{app_name}_{model_name}': form}, **kwargs, ) @classmethod @class_shortcut( call_target__attribute='crud', operation='create', parts__header__children__link__attrs__href='../../..', ) def create(cls, request, call_target, **kwargs): return call_target(request=request, **kwargs) @classmethod @class_shortcut( call_target__attribute='crud', operation='edit', parts__header__children__link__attrs__href='../../../..', ) def edit(cls, request, call_target, **kwargs): return call_target(request=request, **kwargs) @classmethod @class_shortcut( call_target__attribute='crud', operation='delete', parts__header__children__link__attrs__href='../../../..', ) def delete(cls, request, call_target, **kwargs): return call_target(request=request, **kwargs) @classmethod def urls(cls): return Struct( urlpatterns=[ url(r'^$', cls.all_models), url(r'^(?P<app_name>\w+)/(?P<model_name>\w+)/$', cls.list), url(r'^(?P<app_name>\w+)/(?P<model_name>\w+)/create/$', cls.create), url(r'^(?P<app_name>\w+)/(?P<model_name>\w+)/(?P<pk>\d+)/edit/$', cls.edit), url(r'^(?P<app_name>\w+)/(?P<model_name>\w+)/(?P<pk>\d+)/delete/$', cls.delete), ] )
dispatch, Namespace, setdefaults_path, EMPTY, LAST, ) from django.apps import apps from tri_struct import Struct model_by_app_and_name = {(app_name, model_name): model for app_name, models in apps.all_models.items() for model_name, model in models.items()} app_and_name_by_model = {v: k for k, v in model_by_app_and_name.items()} admin_h1 = html.h1(html.a('Admin', attrs__href='/iommi-admin/'), after=0) @dispatch( app=EMPTY, table=EMPTY, ) def all_models(app, table, **kwargs): column_cls = table.call_target.cls.get_meta().member_class def app_data(): for app_name, models in apps.all_models.items(): for name, cls in models.items(): if app.get(app_name, {}).get(name, {}).get('include', True): yield Struct(app_name=app_name, model_name=name, model=cls)
def thanks(request, short): return html.div(html.h1('Thank you for submitting an URL'), html.p('Processing...'), html.a('Submit another', attrs__href='/submit/'))