diff --git a/models/redner_substitution.py b/models/redner_substitution.py
index b9af52c79fd6b6617b41bc54c2071ed91739d921_bW9kZWxzL3JlZG5lcl9zdWJzdGl0dXRpb24ucHk=..c7ee9e306253feb1cd74ab456955898d45f0187a_bW9kZWxzL3JlZG5lcl9zdWJzdGl0dXRpb24ucHk= 100644
--- a/models/redner_substitution.py
+++ b/models/redner_substitution.py
@@ -48,6 +48,7 @@
     (CONSTANT, "Constant value"),
 ]
 
+
 DYNAMIC_PLACEHOLDER_ALLOWED_CONVERTERS = (
     FIELD,
     MAIL_TEMPLATE,
@@ -142,6 +143,38 @@
             ]
         )
 
+    def _build_field(self, sub):
+        if "." in sub.value:
+            path, name = sub.value.rsplit(".", 1)
+        else:
+            path, name = None, sub.value
+        conv = converter.Field(name)
+        if path:
+            conv = converter.relation(path.replace(".", "/"), conv)
+        return conv
+
+    def _build_image(self, sub):
+        if "." in sub.value:
+            path, name = sub.value.rsplit(".", 1)
+        else:
+            path, name = None, sub.value
+        conv = converter.ImageFile(name)
+        if path:
+            conv = converter.relation(path.replace(".", "/"), conv)
+        return conv
+
+    def _build_rel_2_many(self, sub):
+        # Unpack the result of finding a field with its sort order into
+        # variable names.
+        value, sorted = parse_sorted_field(sub.value)
+        conv = converter.RelationToMany(
+            value,
+            None,
+            sortkey=sortkey(sorted) if sorted else None,
+            converter=sub.get_children().build_converter(),
+        )
+        return conv
+
     def build_converter(self):
         d = {}
         for sub in self:
@@ -152,11 +185,5 @@
             elif sub.converter == CONSTANT:
                 conv = converter.Constant(sub.value)
             elif sub.converter == FIELD:
-                if "." in sub.value:
-                    path, name = sub.value.rsplit(".", 1)
-                else:
-                    path, name = None, sub.value
-                conv = converter.Field(name)
-                if path:
-                    conv = converter.relation(path.replace(".", "/"), conv)
+                conv = self._build_field(sub)
             elif sub.converter == IMAGE_FILE:
@@ -162,11 +189,5 @@
             elif sub.converter == IMAGE_FILE:
-                if "." in sub.value:
-                    path, name = sub.value.rsplit(".", 1)
-                else:
-                    path, name = None, sub.value
-                conv = converter.ImageFile(name)
-                if path:
-                    conv = converter.relation(path.replace(".", "/"), conv)
+                conv = self._build_image(sub)
             elif sub.converter == IMAGE_DATAURL:
                 conv = converter.ImageDataURL(sub.value)
             elif sub.converter == QR_CODE_FILE:
@@ -174,15 +195,7 @@
             elif sub.converter == QR_CODE_DATAURL:
                 conv = converter.QRCodeDataURL(sub.value)
             elif sub.converter == RELATION_2MANY:
-                # Unpack the result of finding a field with its sort order into
-                # variable names.
-                value, sorted = parse_sorted_field(sub.value)
-                conv = converter.RelationToMany(
-                    value,
-                    None,
-                    sortkey=sortkey(sorted) if sorted else None,
-                    converter=sub.get_children().build_converter(),
-                )
+                conv = self._build_rel_2_many(sub)
             elif sub.converter == RELATION_PATH:
                 conv = converter.relation(
                     sub.value, sub.get_children().build_converter()