def bind(self, *, parent=None, request=None): assert parent is None or parent._is_bound assert not self._is_bound result = copy.copy(self) if parent: is_root = False iommi_style = get_iommi_style_name(parent) else: is_root = True iommi_style = get_iommi_style_name(self) result = apply_style(iommi_style, result, is_root) result._declared = self del self # to prevent mistakes when changing the code below if parent is None: result._request = request if result._name is None: result._name = 'root' result._iommi_collected_assets = {} result._parent = parent result._bound_members = Struct() result._is_bound = True evaluate_parameters = { **(parent.iommi_evaluate_parameters() if parent is not None else {}), **result.own_evaluate_parameters(), 'traversable': result, } if parent is None: evaluate_parameters['request'] = request result._evaluate_parameters = evaluate_parameters if hasattr(result, 'include'): include = evaluate_strict(result.include, **evaluate_parameters) if not bool(include): return None result.include = True result.on_bind() # on_bind has a chance to hide itself if result.include is False: return None if hasattr(result, 'attrs'): result.attrs = evaluate_attrs(result, **result.iommi_evaluate_parameters()) evaluated_attributes = [k for k, v in items(result.get_declared('refinable_members')) if is_evaluated_refinable(v)] evaluate_members(result, evaluated_attributes, **evaluate_parameters) if hasattr(result, 'extra_evaluated'): result.extra_evaluated = evaluate_strict_container(result.extra_evaluated or {}, **evaluate_parameters) return result
def on_bind(self) -> None: bind_members(self, name='children', unknown_types_fall_through=True) # Fragment children are special and they can be raw str/int etc but # also callables. We need to evaluate them! children = evaluate_strict_container(self.children, **self.iommi_evaluate_parameters()) self.children.update(children) self._bound_members.children._bound_members.update(children)
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 bind(self, *, parent=None, request=None): assert parent is None or parent._is_bound assert not self._is_bound if parent is None: self._request = request if self._name is None: self._name = 'root' result = copy.copy(self) result._declared = self del self # to prevent mistakes when changing the code below result._parent = parent result._is_bound = True evaluate_parameters = { 'traversable': result, **(parent.iommi_evaluate_parameters() if parent is not None else {}), **result.own_evaluate_parameters(), } if parent is None: evaluate_parameters['request'] = request result._evaluate_parameters = evaluate_parameters if hasattr(result, 'include'): include = evaluate_strict(result.include, **evaluate_parameters) if not bool(include): return None else: include = MISSING if include is not MISSING: result.include = True rest_of_style = apply_style(result) # Styling has another chance of setting include to False if include is not MISSING and result.include is False: return None result.include = True result.on_bind() if rest_of_style: rest = apply_style_recursively(style_data=rest_of_style, obj=result) assert not rest, f'There is still styling data left for {result}: {rest_of_style}' # on_bind has a chance to hide itself if result.include is False: return None if hasattr(result, 'attrs'): result.attrs = evaluate_attrs(result, **result.iommi_evaluate_parameters()) evaluated_attributes = [ k for k, v in items(result.get_declared('refinable_members')) if is_evaluated_refinable(v) ] evaluate_members(result, evaluated_attributes, **evaluate_parameters) if hasattr(result, 'extra_evaluated'): result.extra_evaluated = evaluate_strict_container( result.extra_evaluated or {}, **evaluate_parameters) return result
def test_evaluate_strict_container(): assert evaluate_strict_container(Namespace(foo=1)) == Namespace(foo=1) assert evaluate_strict_container(Namespace(foo=lambda foo: foo), foo=3) == Namespace(foo=3)