Пример #1
0
def evaluate_attrs(obj, **kwargs):
    attrs = obj.attrs or {}

    # Micro optimization
    from iommi.debug import iommi_debug_on
    if not attrs and not iommi_debug_on():
        return ''

    return Attrs(
        obj,
        **{
            'class': {
                k: evaluate_strict(v, **kwargs)
                for k, v in items(
                    evaluate_strict(attrs.get('class', {}), **kwargs))
            }
        },
        style={
            k: evaluate_strict(v, **kwargs)
            for k, v in items(evaluate_strict(attrs.get('style', {}), **
                                              kwargs))
        },
        **{
            k: evaluate_strict(v, **kwargs)
            for k, v in items(attrs) if k not in ('class', 'style')
        },
    )
Пример #2
0
    def __init__(self, *, endpoints: Dict[str, Any] = None, include, **kwargs):
        super(Part, self).__init__(include=include, **kwargs)
        collect_members(self, name='endpoints', items=endpoints, cls=Endpoint)

        if iommi_debug_on():
            import inspect
            self._instantiated_at_frame = inspect.currentframe().f_back
Пример #3
0
    def __init__(self, *bases, base_template=None, content_block=None, assets=None, root=None, internal=False, **kwargs):
        self.name = None
        self.internal = internal

        self.base_template = base_template
        if not self.base_template:
            for base in reversed(bases):
                if base.base_template:
                    self.base_template = base.base_template
                    break

        self.content_block = content_block
        if not self.content_block:
            for base in reversed(bases):
                if base.content_block:
                    self.content_block = base.content_block
                    break

        if assets:
            from iommi.debug import iommi_debug_on
            if iommi_debug_on():
                print("Warning: The preferred way to add top level assets config to a Style is via the root argument. "
                      "I.e. assets__* becomes root__assets__*")
            setdefaults_path(root, assets=assets)

        self.root = {k: v for k, v in items(Namespace(*(base.root for base in bases), root)) if v is not None}
        self.config = Namespace(*[x.config for x in bases], recursive_namespace(kwargs))
Пример #4
0
def render_root(*,
                part,
                template_name=MISSING,
                content_block_name=MISSING,
                context,
                **render):
    assert part._is_bound
    if template_name is MISSING:
        template_name = getattr(settings, 'IOMMI_BASE_TEMPLATE',
                                DEFAULT_BASE_TEMPLATE)

        try:
            get_template(template_name)
        except TemplateDoesNotExist:
            template_name = f'iommi/base_{get_style_for(part)}.html'

    if content_block_name is MISSING:
        content_block_name = getattr(settings, 'IOMMI_CONTENT_BLOCK',
                                     DEFAULT_CONTENT_BLOCK)

    title = getattr(part, 'title', '')
    from iommi.debug import iommi_debug_panel
    from iommi import Page
    context = dict(
        content=part.__html__(**render),
        title=title if title not in (None, MISSING) else '',
        iommi_debug_panel=iommi_debug_panel(part) if iommi_debug_on() else '',
        **(part.context if isinstance(part, Page) else {}),
        **context,
    )

    template_string = '{% extends "' + template_name + '" %} {% block ' + content_block_name + ' %}{{ iommi_debug_panel }}{{ content }}{% endblock %}'
    return get_template_from_string(template_string).render(
        context=context, request=part.get_request())
Пример #5
0
    def __init__(self, parent, **attrs):
        from iommi.debug import iommi_debug_on

        if iommi_debug_on() and getattr(parent, '_name', None) is not None:
            attrs['data-iommi-path'] = parent.iommi_dunder_path
            attrs['data-iommi-type'] = type(parent).__name__

        super(Attrs, self).__init__(attrs)
Пример #6
0
    def on_bind(self) -> None:
        if self.attr is MISSING:
            self.attr = self._name

        # Not strict evaluate on purpose
        self.model = evaluate(self.model, **self.iommi_evaluate_parameters())

        if self.model and self.include:
            try:
                self.search_fields = get_search_fields(model=self.model)
            except NoRegisteredSearchFieldException:
                self.search_fields = ['pk']
                if iommi_debug_on():
                    print(f'Warning: falling back to primary key as lookup and sorting on {self._name}. \nTo get rid of this warning and get a nicer lookup and sorting use register_search_fields.')
Пример #7
0
def evaluate_attrs(obj, **kwargs):
    attrs = obj.attrs or {}

    # Micro optimization
    from iommi.debug import iommi_debug_on

    if not attrs and not iommi_debug_on():
        return ''

    classes = evaluate_strict(attrs.get('class', {}), **kwargs)

    assert not isinstance(
        classes, str
    ), """CSS classes needs to be specified as dicts, not as strings. So you want something like:
    field__class__foo=True

or

    field__class={'foo-bar': true}"""

    styles = evaluate_strict(attrs.get('style', {}), **kwargs)

    assert not isinstance(
        styles, str
    ), """CSS styles needs to be specified as dicts, not as strings. So you want something like:
        field__style__display='none'

    or

        field__style={'background-color': 'blue'}"""

    return Attrs(
        obj,
        **{
            'class':
            {k: evaluate_strict(v, **kwargs)
             for k, v in items(classes)}
        },
        style={k: evaluate_strict(v, **kwargs)
               for k, v in items(styles)},
        **{
            k: evaluate_strict(v, **kwargs)
            for k, v in items(attrs) if k not in ('class', 'style')
        },
    )
Пример #8
0
    def on_bind(self) -> None:
        assert self.template

        form = self.iommi_parent().iommi_parent()
        if self.attr is MISSING:
            self.attr = self._name
        if self.display_name is MISSING:
            self.display_name = capitalize(self._name).replace('_', ' ') if self._name else ''

        self.errors = Errors(parent=self, **self.errors)

        if form.editable is False:
            self.editable = False

        # Not strict evaluate on purpose
        self.model = evaluate(self.model, **self.iommi_evaluate_parameters())

        self.choices = evaluate_strict(self.choices, **self.iommi_evaluate_parameters())

        self.initial = evaluate_strict(self.initial, **self.iommi_evaluate_parameters())
        self._read_initial()

        self._read_raw_data()

        self.parsed_data = evaluate_strict(self.parsed_data, **self.iommi_evaluate_parameters())
        self._parse()

        self._validate()

        self.input = self.input.bind(parent=self)
        self.label = self.label.bind(parent=self)
        assert not self.label.children
        self.label.children = dict(text=evaluate_strict(self.display_name, **self.iommi_evaluate_parameters()))
        self.non_editable_input = self.non_editable_input.bind(parent=self)

        if self.model and self.include:
            try:
                self.search_fields = get_search_fields(model=self.model)
            except NoRegisteredSearchFieldException:
                self.search_fields = ['pk']
                if iommi_debug_on():
                    print(f'Warning: falling back to primary key as lookup and sorting on {self._name}. \nTo get rid of this warning and get a nicer lookup and sorting use register_search_fields.')
Пример #9
0
def render_root(*, part, context, **render):
    assert part._is_bound
    root_style_name = get_iommi_style_name(part)
    root_style = get_style(root_style_name)
    template_name = root_style.base_template
    content_block_name = root_style.content_block

    # Render early so that all the binds are forced before we look at all_assets,
    # since they are populated as a side-effect
    content = part.__html__(**render)

    assets = part.iommi_collected_assets()

    assert template_name, f"{root_style_name} doesn't have a base_template defined"
    assert content_block_name, f"{root_style_name} doesn't have a content_block defined"

    title = get_title(part)

    from iommi.debug import iommi_debug_panel
    from iommi import Page
    from iommi.fragment import Container

    context = dict(
        container=Container(_name='Container').bind(parent=part),
        content=content,
        title=title if title not in (None, MISSING) else '',
        iommi_debug_panel=iommi_debug_panel(part) if iommi_debug_on()
        and '_iommi_disable_debug_panel' not in part.get_request().GET else '',
        assets=assets,
        **(part.context if isinstance(part, Page) else {}),
        **context,
    )

    template_string = ('{% extends "' + template_name + '" %} {% block ' +
                       content_block_name +
                       ' %}{{ iommi_debug_panel }}{{ content }}{% endblock %}')
    return get_template_from_string(template_string).render(
        context=context, request=part.get_request())
Пример #10
0
def render_root(*, part, context, **render):
    assert part._is_bound
    root_style_name = get_style_name_for(part)
    root_style = get_style(root_style_name)
    template_name = root_style.base_template
    content_block_name = root_style.content_block

    assert template_name, f"{root_style_name} doesn't have a base_template defined"
    assert content_block_name, f"{root_style_name} doesn't have a content_block defined"

    title = getattr(part, 'title', None)

    if title is None:
        parts = getattr(part, 'parts', None)
        if parts is not None:
            for p in parts.values():
                title = getattr(p, 'title', None)
                if title is not None:
                    break

    from iommi.debug import iommi_debug_panel
    from iommi import Page
    from iommi.fragment import Container

    context = dict(
        container=Container(_name='Container').bind(parent=part),
        content=part.__html__(**render),
        title=title if title not in (None, MISSING) else '',
        iommi_debug_panel=iommi_debug_panel(part) if iommi_debug_on() else '',
        **(part.context if isinstance(part, Page) else {}),
        **context,
    )

    template_string = '{% extends "' + template_name + '" %} {% block ' + content_block_name + ' %}{{ iommi_debug_panel }}{{ content }}{% endblock %}'
    return get_template_from_string(template_string).render(
        context=context, request=part.get_request())
Пример #11
0
        attrs__src=
        'https://cdn.jsdelivr.net/npm/[email protected]/dist/js/select2.min.js',
    ),
    select2_css=Asset.css(attrs=dict(
        href=
        'https://cdn.jsdelivr.net/npm/[email protected]/dist/css/select2.min.css',
    )),
)

base = Style(
    internal=True,
    base_template='iommi/base.html',
    content_block='content',
    root=dict(
        endpoints__debug_tree=dict(
            include=lambda endpoint, **_: iommi_debug_on(),
            func=endpoint__debug_tree,
        ),
        assets=dict(
            jquery=Asset.js(
                attrs=dict(
                    src='https://code.jquery.com/jquery-3.4.1.js',
                    integrity=
                    'sha256-WpOohJOqMqqyKL9FccASB9O0KwACQJpFTUBLTYOVvVU=',
                    crossorigin='anonymous',
                ),
                after=-1,
            ),
            axios=Asset.js(
                attrs=dict(
                    src=
Пример #12
0
class Page(Part):
    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,
        endpoints__debug_tree=Namespace(
            include=lambda endpoint, **_: iommi_debug_on(),
            func=endpoint__debug_tree,
        ),
        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 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, 'context 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)