Skip to content

Commit

Permalink
✨ [#1451] -- implement render nodes for Formio component types
Browse files Browse the repository at this point in the history
  • Loading branch information
sergei-maertens committed May 2, 2022
1 parent f4c1e18 commit 92bb23f
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 7 deletions.
1 change: 1 addition & 0 deletions src/openforms/conf/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@
"openforms.emails",
"openforms.formio",
"openforms.formio.formatters.apps.FormIOFormattersApp",
"openforms.formio.rendering",
"openforms.forms",
"openforms.multidomain",
"openforms.products",
Expand Down
7 changes: 0 additions & 7 deletions src/openforms/formio/rendering/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,3 @@
a more specific subclass using the registry. The vanilla Formio components requiring
special attention are implemented in :mod:`openforms.submissions.rendering.default`.
"""
from .nodes import ComponentNode
from .registry import register

__all__ = [
"register",
"ComponentNode",
]
10 changes: 10 additions & 0 deletions src/openforms/formio/rendering/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from django.apps import AppConfig


class FormioRenderingConfig(AppConfig):
name = "openforms.formio.rendering"
label = "formio_rendering"

def ready(self):
# register plugins
from . import default # noqa
102 changes: 102 additions & 0 deletions src/openforms/formio/rendering/default.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
from typing import Iterator, Union

from django.utils.safestring import SafeString, mark_safe

from openforms.emails.utils import strip_tags_plus # TODO: put somewhere else
from openforms.submissions.rendering.constants import RenderModes

from ..utils import iter_components
from .conf import RENDER_CONFIGURATION
from .nodes import ComponentNode
from .registry import register


class ContainerMixin:
is_layout = True

@property
def is_visible(self) -> bool:
# fieldset does not support the showInFoo properties, so we don't use the super
# class.
if self.mode == RenderModes.export:
return True

if self.component.get("hidden") is True:
return False

render_configuration = RENDER_CONFIGURATION[self.mode]
if render_configuration.key is not None:
assert render_configuration.key not in self.component, (
f"Component type {self.component['type']} unexpectedly seems to support "
f"the {render_configuration.key} property!"
)

any_children_visible = any((child.is_visible for child in self.get_children()))
if not any_children_visible:
return False

return True


@register("fieldset")
class FieldSetNode(ContainerMixin, ComponentNode):
layout_modifier = "fieldset"


@register("columns")
class ColumnsNode(ContainerMixin, ComponentNode):
layout_modifier = "columns"

def get_children(self) -> Iterator["ComponentNode"]:
"""
Columns has a extra nested structure contained within.
.. code-block:: python
{
"type": "columns",
"columns": [
{
"size": 6,
"components": [...],
},
{
"size": 6,
"components": [...],
}
],
}
"""
for column in self.component["columns"]:
for component in iter_components(
configuration=column, recursive=False, _is_root=False
):
yield ComponentNode.build_node(
step=self.step,
component=component,
renderer=self.renderer,
depth=self.depth + 1,
)


@register("content")
class WYSIWYGNode(ComponentNode):
@property
def is_visible(self) -> bool:
visible_from_config = super().is_visible
if not visible_from_config:
return False
return self.mode in (
# RenderModes.cli,
RenderModes.pdf,
)

@property
def value(self) -> Union[str, SafeString]:
content = self.component["html"]
if self.as_html:
return mark_safe(content)

content_without_tags = strip_tags_plus(content)
return content_without_tags.rstrip()

0 comments on commit 92bb23f

Please sign in to comment.