Example #1
0
def fragment__render(fragment, context):
    if not fragment.include:
        return ''

    rendered_children = fragment.render_text_or_children(context=context)

    if fragment.template:
        return render_template(fragment.get_request(), fragment.template, dict(**context, **fragment.iommi_evaluate_parameters(), rendered_children=rendered_children))

    is_void_element = fragment.tag in _void_elements

    if fragment.tag:
        if rendered_children:
            assert not is_void_element, f'{fragment.tag} is a void element, but it has children: {rendered_children}'
            return format_html(
                '<{tag}{attrs}>{children}</{tag}>',
                tag=fragment.tag,
                attrs=render_attrs(fragment.attrs),
                children=rendered_children,
            )
        else:
            return format_html(
                '<{tag}{attrs}>' if is_void_element else '<{tag}{attrs}></{tag}>',
                tag=fragment.tag,
                attrs=render_attrs(fragment.attrs),
            )

    else:
        return format_html(
            '{}',
            rendered_children,
        )
Example #2
0
    def render_fields(self):
        r = []
        for field in values(self.fields):
            r.append(field.__html__())

        # We need to preserve all other GET parameters, so we can e.g. filter in two forms on the same page, and keep sorting after filtering
        own_field_paths = {f.iommi_path for f in values(self.fields)}
        for k, v in items(self.get_request().GET):
            if k not in own_field_paths and not k.startswith('-'):
                r.append(format_html('<input type="hidden" name="{}" value="{}" />', k, v))

        return format_html('{}\n' * len(r), *r)
Example #3
0
def test_as_html():
    # str case
    assert format_html('{}', as_html(part='foo', context={})) == 'foo'
    assert format_html('{}',
                       as_html(part='<foo>bar</foo>',
                               context={})) == '&lt;foo&gt;bar&lt;/foo&gt;'
    assert format_html('{}',
                       as_html(part=mark_safe('<foo>bar</foo>'),
                               context={})) == '<foo>bar</foo>'

    # Template case
    c = RequestContext(req('get'))
    assert format_html('{}', as_html(part=Template('foo'), context=c)) == 'foo'
    assert format_html('{}', as_html(part=Template('<foo>bar</foo>'),
                                     context=c)) == '<foo>bar</foo>'

    # __html__ attribute case
    assert format_html(
        '{}', as_html(part=Struct(__html__=lambda context: 'foo'),
                      context={})) == 'foo'
    assert format_html(
        '{}',
        as_html(part=Struct(__html__=lambda context: '<foo>bar</foo>'),
                context={})) == '&lt;foo&gt;bar&lt;/foo&gt;'
    assert format_html(
        '{}',
        as_html(
            part=Struct(__html__=lambda context: mark_safe('<foo>bar</foo>')),
            context={})) == '<foo>bar</foo>'
Example #4
0
 def render_text_or_children(self, context):
     request = self.get_request()
     return format_html(
         '{}' * len(self.children), *[
             as_html(part=x, context=context, request=request)
             for x in values(self.children)
         ])
Example #5
0
def dunder_path__format(row, **_):
    if row.dunder_path is None:
        return ''
    prefix = row.dunder_path.rpartition('__')[0]
    return format_html(
        '<span class="full-path">{prefix}{separator}</span>{name}',
        prefix=prefix,
        separator='__' if prefix else '',
        name=row.name)
Example #6
0
    def render_fields(self):
        r = []
        for field in self.fields.values():
            r.append(field.__html__())

        if self.is_full_form:
            r.append(format_html(AVOID_EMPTY_FORM, self.path()))

        # We need to preserve all other GET parameters, so we can e.g. filter in two forms on the same page, and keep sorting after filtering
        own_field_paths = {f.path() for f in self.fields.values()}
        for k, v in self.request().GET.items():
            if k == self.own_target_marker():
                continue
            # TODO: why is there a special case for '-' here? shouldn't it be self.own_target_marker or something?
            if k not in own_field_paths and k != '-':
                r.append(
                    format_html('<input type="hidden" name="{}" value="{}" />',
                                k, v))

        return format_html('{}\n' * len(r), *r)
Example #7
0
 def icon(cls,
          icon,
          *,
          display_name=None,
          call_target=None,
          icon_classes=None,
          **kwargs):
     icon_classes_str = ' '.join(
         ['fa-' + icon_class
          for icon_class in icon_classes]) if icon_classes else ''
     if icon_classes_str:
         icon_classes_str = ' ' + icon_classes_str
     setdefaults_path(
         kwargs,
         display_name=format_html('<i class="fa fa-{}{}"></i> {}', icon,
                                  icon_classes_str, display_name),
     )
     return call_target(**kwargs)
Example #8
0
def test_format_html3():
    assert render_template(
        req('get'), Template('{{foo}}'),
        dict(foo=format_html('{}', format_html(
            '<a href="foo">foo</a>')))) == '<a href="foo">foo</a>'
Example #9
0
def test_format_html():
    assert format_html('<{a}>{b}{c}', a='a', b=format_html('<b>'),
                       c='<c>') == '<a><b>&lt;c&gt;'
Example #10
0
 def iommi_close_tag(self):
     if self.tag is None:
         return ''
     else:
         return format_html('</{}>', self.tag)
Example #11
0
 def iommi_open_tag(self):
     if self.tag is None:
         return ''
     else:
         return format_html('<{}{}>', self.tag, self.attrs)
Example #12
0
def test_fragment__render__simple_cases():
    assert format_html('{}', html.h1('foo')) == '<h1 >foo</h1>'
    assert format_html('{}', Fragment('foo<foo>')) == 'foo&lt;foo&gt;'
Example #13
0
class Page(Part):
    """
    A page is used to compose iommi parts into a bigger whole.

    See the `howto <https://docs.iommi.rocks/en/latest/howto.html#parts-pages>`_ for example usages.
    """

    title: str = EvaluatedRefinable()
    member_class: Type[Fragment] = Refinable()
    context = Refinable(
    )  # context is evaluated, but in a special way so gets no EvaluatedRefinable type

    class Meta:
        member_class = Fragment

    @reinvokable
    @dispatch(
        parts=EMPTY,
        context=EMPTY,
    )
    def __init__(self,
                 *,
                 _parts_dict: Dict[str, PartType] = None,
                 parts: dict,
                 **kwargs):
        super(Page, self).__init__(**kwargs)

        self.parts = {
        }  # This is just so that the repr can survive if it gets triggered before parts is set properly

        # First we have to up sample parts that aren't Part into Fragment
        def as_fragment_if_needed(k, v):
            if v is None:
                return None
            if not isinstance(v, (dict, Traversable)):
                return Fragment(children__text=v, _name=k)
            else:
                return v

        _parts_dict = {
            k: as_fragment_if_needed(k, v)
            for k, v in items(_parts_dict)
        }
        parts = Namespace(
            {k: as_fragment_if_needed(k, v)
             for k, v in items(parts)})

        collect_members(self,
                        name='parts',
                        items=parts,
                        items_dict=_parts_dict,
                        cls=self.get_meta().member_class)

    def on_bind(self) -> None:
        bind_members(self, name='parts')
        if self.context and self.iommi_parent() != None:
            assert False, 'The context property is only valid on the root page'

    def own_evaluate_parameters(self):
        return dict(page=self)

    @dispatch(render=lambda rendered: format_html('{}' * len(rendered),
                                                  *values(rendered)))
    def __html__(self, *, render=None):
        self.context = evaluate_strict_container(
            self.context or {}, **self.iommi_evaluate_parameters())
        rendered = {
            name: as_html(request=self.get_request(),
                          part=part,
                          context=self.iommi_evaluate_parameters())
            for name, part in items(self.parts)
        }

        return render(rendered)

    def as_view(self):
        return build_as_view_wrapper(self)