Example #1
0
    def handle_block(self, block_type, block_value):
        if hasattr(block_type, "get_translatable_segments"):
            return block_type.get_translatable_segments(block_value)

        elif isinstance(block_type, (blocks.CharBlock, blocks.TextBlock)):
            return [SegmentValue("", block_value)]

        elif isinstance(block_type, blocks.RichTextBlock):
            template, texts = extract_html_segments(block_value.source)

            return [TemplateValue("", "html", template, len(texts))] + [
                SegmentValue.from_html("", text) for text in texts
            ]

        elif isinstance(block_type, (ImageChooserBlock, SnippetChooserBlock)):
            return self.handle_related_object_block(block_value)

        elif isinstance(block_type, blocks.StructBlock):
            return self.handle_struct_block(block_value)

        elif isinstance(block_type, blocks.ListBlock):
            return self.handle_list_block(block_value)

        elif isinstance(block_type, blocks.StreamBlock):
            return self.handle_stream_block(block_value)

        elif isinstance(block_type, blocks.ChoiceBlock):
            return []

        else:
            raise Exception(
                "Unrecognised StreamField block type '{}'. Have you implemented get_translatable_segments on this class?".format(
                    block_type.__class__.__name__
                )
            )
 def test_text(self):
     segment = SegmentValue.from_html(
         "foo",
         "This is a paragraph. <b>This is some bold <i>and now italic</i></b> text",
     )
     self.assertEqual(
         segment.text,
         "This is a paragraph. This is some bold and now italic text")
 def test_html_with_ids(self):
     segment = SegmentValue.from_html(
         "foo",
         '<b>Bread</b>\xa0is a\xa0<a href="https://en.wikipedia.org/wiki/Staple_food">staple food</a>\xa0prepared from a\xa0<a href="https://en.wikipedia.org/wiki/Dough">dough</a>\xa0of\xa0<a href="https://en.wikipedia.org/wiki/Flour">flour</a>\xa0and\xa0<a href="https://en.wikipedia.org/wiki/Water">water</a>, usually by\xa0<a href="https://en.wikipedia.org/wiki/Baking">baking</a>. Throughout recorded history it has been popular around the world and is one of the oldest artificial foods, having been of importance since the dawn of\xa0<a href="https://en.wikipedia.org/wiki/Agriculture#History">agriculture</a>.',
     )
     self.assertEqual(
         segment.html_with_ids,
         '<b>Bread</b> is a <a id="a1">staple food</a> prepared from a <a id="a2">dough</a> of <a id="a3">flour</a> and <a id="a4">water</a>, usually by <a id="a5">baking</a>. Throughout recorded history it has been popular around the world and is one of the oldest artificial foods, having been of importance since the dawn of <a id="a6">agriculture</a>.',
     )
    def test_replace_html_attrs(self):
        segment = SegmentValue.from_html(
            "foo.bar",
            'This is some text. &lt;foo&gt; <b>Bold text</b> <a id="a1">A link and some more <b>Bold text</b></a>',
        )

        segment.replace_html_attrs(
            {"a#a1": {
                "href": "http://changed-example.com"
            }})

        self.assertEqual(
            segment.html,
            'This is some text. &lt;foo&gt; <b>Bold text</b> <a href="http://changed-example.com">A link and some more <b>Bold text</b></a>',
        )
    def test_segment_value(self):
        segment = SegmentValue.from_html(
            "foo.bar",
            'This is some text. &lt;foo&gt; <b>Bold text</b> <a href="http://example.com">A link and some more <b>Bold text</b></a>',
        )

        self.assertEqual(segment.path, "foo.bar")
        self.assertEqual(segment.order, 0)
        self.assertEqual(
            segment.text,
            "This is some text. <foo> Bold text A link and some more Bold text",
        )
        self.assertEqual(
            segment.html_elements,
            [
                SegmentValue.HTMLElement(25, 34, "b1", ("b", {})),
                SegmentValue.HTMLElement(56, 65, "b2", ("b", {})),
                SegmentValue.HTMLElement(35, 65, "a1",
                                         ("a", {
                                             "href": "http://example.com"
                                         })),
            ],
        )
        self.assertEqual(
            segment.html,
            'This is some text. &lt;foo&gt; <b>Bold text</b> <a href="http://example.com">A link and some more <b>Bold text</b></a>',
        )
        self.assertEqual(
            segment.html_with_ids,
            'This is some text. &lt;foo&gt; <b>Bold text</b> <a id="a1">A link and some more <b>Bold text</b></a>',
        )
        self.assertEqual(segment.get_html_attrs(),
                         {"a#a1": {
                             "href": "http://example.com"
                         }})

        # .with_order()
        orderred = segment.with_order(123)
        self.assertEqual(segment.order, 0)
        self.assertEqual(orderred.order, 123)
        self.assertEqual(orderred.path, "foo.bar")
        self.assertEqual(orderred.text, segment.text)
        self.assertEqual(orderred.html_elements, segment.html_elements)
        self.assertEqual(orderred.html, segment.html)
        self.assertEqual(orderred.html_with_ids, segment.html_with_ids)

        # .wrap()
        wrapped = segment.wrap("baz")
        self.assertEqual(segment.path, "foo.bar")
        self.assertEqual(wrapped.path, "baz.foo.bar")
        self.assertEqual(wrapped.order, segment.order)
        self.assertEqual(wrapped.text, segment.text)
        self.assertEqual(wrapped.html_elements, segment.html_elements)
        self.assertEqual(wrapped.html, segment.html)
        self.assertEqual(wrapped.html_with_ids, segment.html_with_ids)

        # .unwrap()
        path_component, unwrapped = segment.unwrap()
        self.assertEqual(segment.path, "foo.bar")
        self.assertEqual(path_component, "foo")
        self.assertEqual(unwrapped.path, "bar")
        self.assertEqual(unwrapped.order, segment.order)
        self.assertEqual(unwrapped.text, segment.text)
        self.assertEqual(unwrapped.html_elements, segment.html_elements)
        self.assertEqual(unwrapped.html, segment.html)
        self.assertEqual(unwrapped.html_with_ids, segment.html_with_ids)
Example #6
0
def extract_segments(instance):
    segments = []

    for translatable_field in instance.get_translatable_fields():
        field = translatable_field.get_field(instance.__class__)

        if hasattr(field, "get_translatable_segments"):
            segments.extend(
                segment.wrap(field.name)
                for segment in field.get_translatable_segments(
                    field.value_from_object(instance)
                )
            )

        elif isinstance(field, StreamField):
            segments.extend(
                segment.wrap(field.name)
                for segment in StreamFieldSegmentExtractor(field).handle_stream_block(
                    field.value_from_object(instance)
                )
            )

        elif isinstance(field, RichTextField):
            template, texts = extract_html_segments(field.value_from_object(instance))

            field_segments = [TemplateValue("", "html", template, len(texts))] + [
                SegmentValue.from_html("", text) for text in texts
            ]

            segments.extend(segment.wrap(field.name) for segment in field_segments)

        elif isinstance(field, (models.TextField, models.CharField)):
            if not field.choices:
                segments.append(
                    SegmentValue(field.name, field.value_from_object(instance))
                )

        elif isinstance(field, (models.ForeignKey)) and issubclass(
            field.related_model, TranslatableMixin
        ):
            related_instance = getattr(instance, field.name)

            if related_instance:
                segments.append(
                    RelatedObjectValue.from_instance(field.name, related_instance)
                )

        elif (
            isinstance(field, (models.ManyToOneRel))
            and isinstance(field.remote_field, ParentalKey)
            and issubclass(field.related_model, TranslatableMixin)
        ):
            manager = getattr(instance, field.name)

            for child_instance in manager.all():
                segments.extend(
                    segment.wrap(str(child_instance.translation_key)).wrap(field.name)
                    for segment in extract_segments(child_instance)
                )

    class Counter:
        def __init__(self):
            self.value = 0

        def next(self):
            self.value += 1
            return self.value

    counter = Counter()

    return [
        segment.with_order(counter.next())
        for segment in segments
        if not segment.is_empty()
    ]