From a24acad07a16fc0e1e6a6485eb18794471d426d4 Mon Sep 17 00:00:00 2001 From: Pawel Kowalski Date: Thu, 16 Aug 2018 15:00:37 +0200 Subject: [PATCH 1/5] Add image_block serialization suitable for a SPA, i.e. return path, not the internal id of an image --- server/api/graphene_wagtail.py | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/server/api/graphene_wagtail.py b/server/api/graphene_wagtail.py index d283b851..51ee130a 100644 --- a/server/api/graphene_wagtail.py +++ b/server/api/graphene_wagtail.py @@ -4,12 +4,41 @@ from graphene.types import Scalar from graphene_django.converter import convert_django_field from wagtail.core.fields import StreamField +from wagtail.images.models import Image class GenericStreamFieldType(Scalar): @staticmethod def serialize(stream_value): - return stream_value.stream_data + stream_data = stream_value.stream_data + + for d in stream_data: + if isinstance(d, dict): + _type = d['type'] + if _type == 'image_block': + _value = d['value'] + value = { + # 'value': _value, + # 'id': d['id'], + 'path': Image.objects.get(id=_value).file.url + } + d['value'] = value + + # value = dict(d['value']) + # if 'document' in value: + # value['document'] = Document.objects.get(id=value['document']).file.url + # if 'image' in value: + # value['image'] = Image.objects.get(id=value['image']).file.url + + # else: + # _type = d[0] + # value = dict(d[1]) + # if 'document' in value: + # value['document'] = value['document'].file.url + # if 'image' in value: + # value['image'] = value['image'].file.url + + return stream_data @convert_django_field.register(StreamField) From 80719e9a65bcc943881597c2049e0b3039ad4169 Mon Sep 17 00:00:00 2001 From: Pawel Kowalski Date: Thu, 16 Aug 2018 15:23:41 +0200 Subject: [PATCH 2/5] Enrich test data generation with ImageFields --- server/book/blocks.py | 2 +- server/book/factories.py | 16 ++++++++++++++-- server/core/management/commands/dummy_data.py | 4 ++-- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/server/book/blocks.py b/server/book/blocks.py index d8917e2d..24b28dac 100644 --- a/server/book/blocks.py +++ b/server/book/blocks.py @@ -5,7 +5,7 @@ DEFAULT_RICH_TEXT_FEATURES = ['bold', 'italic', 'link', 'ol', 'ul'] # 'text_block' 'task' class TextBlock(blocks.StructBlock): - text = blocks.CharBlock() + text = blocks.RichTextBlock() # 'modal_text' diff --git a/server/book/factories.py b/server/book/factories.py index d13f5bb8..e0066b6e 100644 --- a/server/book/factories.py +++ b/server/book/factories.py @@ -4,6 +4,7 @@ import factory import wagtail_factories from factory import CREATE_STRATEGY +from wagtail.core.rich_text import RichText from book.blocks import ModalTextBlock from book.models import Book, Topic, Module, Chapter, ContentBlock, TextBlock @@ -56,6 +57,9 @@ class ModalTextBlockFactory(wagtail_factories.StructBlockFactory): model = ModalTextBlock +block_types = ['text_block', 'modal_text', 'student_entry', 'image_block', 'task'] + + class ContentBlockFactory(BasePageFactory): class Meta: model = ContentBlock @@ -65,6 +69,7 @@ class ContentBlockFactory(BasePageFactory): contents = wagtail_factories.StreamFieldFactory({ 'text_block': TextBlockFactory, 'modal_text': ModalTextBlockFactory, + 'image_block': wagtail_factories.ImageChooserBlockFactory }) @classmethod @@ -73,11 +78,18 @@ class ContentBlockFactory(BasePageFactory): for idx, resource in enumerate(kwargs[stream_field_name]): value = resource['value'] for jdx, field in enumerate(value): - kwargs['{}__{}__{}__{}'.format(stream_field_name, idx, resource['type'], field)] = value[field] + kwargs['{}__{}__{}__{}'.format(stream_field_name, idx, resource['type'], field)] = RichText(value[field]) del kwargs[stream_field_name] else: for i in range(0, random.randint(3, 7)): - kwargs['{}__{}__{}__b'.format(stream_field_name, i, 'text_block', 'text')] = fake_title_noparam() + block_type = random.choice(block_types) + if block_type == 'text_block': + kwargs['{}__{}__{}__{}'.format(stream_field_name, i, 'text_block', 'text')] = RichText(fake_title_noparam()) + elif block_type == 'image_block': + kwargs['{}__{}__{}__{}'.format(stream_field_name, i, 'image_block', 'image__title')] = fake_title_noparam() + + # for i in range(4, 6): + # kwargs['{}__{}__{}__{}'.format(stream_field_name, i, 'image_block', 'image')] = '' @classmethod def create(cls, **kwargs): diff --git a/server/core/management/commands/dummy_data.py b/server/core/management/commands/dummy_data.py index b55b0a76..410dfa35 100644 --- a/server/core/management/commands/dummy_data.py +++ b/server/core/management/commands/dummy_data.py @@ -69,14 +69,14 @@ data = [ 'type': 'text_block', 'value': { 'type': 'text_block', - 'text': 'Sie haben diesen Sommer ihre Lehre begonnen. Was bedeutet dieser neue Abschnitt für Sie?\nHalten Sie Ihre Erfahrungen im Bereich fest und stellen Sie diese anschliessend der Klasse vor.' + 'text': '

Sie haben diesen Sommer ihre Lehre begonnen. Was bedeutet dieser neue Abschnitt für Sie?
Halten Sie Ihre Erfahrungen im Bereich fest und stellen Sie diese anschliessend der Klasse vor.

' } }, { 'type': 'text_block', 'value': { 'type': 'text_block', - 'text': 'Das folgende Interview bezieht sich auf Jugendliche, die Ihre Lehre im Sommer begonnen haben. Lesen Sie das Interview durch und bearbeiten Sie anschliessend die Aufgaben.' + 'text': '

Das folgende Interview bezieht sich auf Jugendliche, die Ihre Lehre im Sommer begonnen haben.

Lesen Sie das Interview durch und bearbeiten Sie anschliessend die Aufgaben.

' } }, # { From ef4fb4b20e93408f165b4b375c1ea22fa246a01d Mon Sep 17 00:00:00 2001 From: Pawel Kowalski Date: Thu, 16 Aug 2018 15:48:46 +0200 Subject: [PATCH 3/5] Generate all types of content --- server/book/blocks.py | 6 +++--- server/book/factories.py | 24 ++++++++++++++++++------ 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/server/book/blocks.py b/server/book/blocks.py index 24b28dac..c6849198 100644 --- a/server/book/blocks.py +++ b/server/book/blocks.py @@ -10,13 +10,13 @@ class TextBlock(blocks.StructBlock): # 'modal_text' class ModalTextBlock(blocks.StructBlock): - description = blocks.CharBlock() - modal_content = blocks.CharBlock() + description = blocks.RichTextBlock() + url = blocks.URLBlock() # 'student_entry' class StudentEntryBlock(blocks.StructBlock): - task_text = blocks.CharBlock() + task_text = blocks.RichTextBlock() # 'text_block' 'task' 'modal_text' 'student_entry' 'image_block' diff --git a/server/book/factories.py b/server/book/factories.py index e0066b6e..d6f64df2 100644 --- a/server/book/factories.py +++ b/server/book/factories.py @@ -6,7 +6,7 @@ import wagtail_factories from factory import CREATE_STRATEGY from wagtail.core.rich_text import RichText -from book.blocks import ModalTextBlock +from book.blocks import ModalTextBlock, StudentEntryBlock from book.models import Book, Topic, Module, Chapter, ContentBlock, TextBlock from core.factories import BasePageFactory, fake, DummyImageFactory, fake_title, fake_title_noparam @@ -51,12 +51,18 @@ class TextBlockFactory(wagtail_factories.StructBlockFactory): class ModalTextBlockFactory(wagtail_factories.StructBlockFactory): description = factory.LazyAttribute(fake_title) - modal_content = factory.LazyAttribute(fake_title) + url = factory.LazyAttribute(lambda x: fake.uri()) class Meta: model = ModalTextBlock +class StudentEntryBlockFactory(wagtail_factories.StructBlockFactory): + + class Meta: + model = StudentEntryBlock + + block_types = ['text_block', 'modal_text', 'student_entry', 'image_block', 'task'] @@ -69,7 +75,9 @@ class ContentBlockFactory(BasePageFactory): contents = wagtail_factories.StreamFieldFactory({ 'text_block': TextBlockFactory, 'modal_text': ModalTextBlockFactory, - 'image_block': wagtail_factories.ImageChooserBlockFactory + 'student_entry': StudentEntryBlockFactory, + 'image_block': wagtail_factories.ImageChooserBlockFactory, + 'task': TextBlockFactory }) @classmethod @@ -85,11 +93,15 @@ class ContentBlockFactory(BasePageFactory): block_type = random.choice(block_types) if block_type == 'text_block': kwargs['{}__{}__{}__{}'.format(stream_field_name, i, 'text_block', 'text')] = RichText(fake_title_noparam()) + elif block_type == 'modal_text': + kwargs['{}__{}__{}__{}'.format(stream_field_name, i, 'modal_text', 'description')] = RichText(fake_title_noparam()) + # kwargs['{}__{}__{}__{}'.format(stream_field_name, i, 'modal_text', 'description')] = ..url.. + elif block_type == 'student_entry': + kwargs['{}__{}__{}__{}'.format(stream_field_name, i, 'student_entry', 'task_text')] = RichText(fake_title_noparam()) elif block_type == 'image_block': kwargs['{}__{}__{}__{}'.format(stream_field_name, i, 'image_block', 'image__title')] = fake_title_noparam() - - # for i in range(4, 6): - # kwargs['{}__{}__{}__{}'.format(stream_field_name, i, 'image_block', 'image')] = '' + elif block_type == 'task': + kwargs['{}__{}__{}__{}'.format(stream_field_name, i, 'task', 'text')] = RichText(fake_title_noparam()) @classmethod def create(cls, **kwargs): From a512ef4f635c85e55b5c5867b9c46ca9b3dcc149 Mon Sep 17 00:00:00 2001 From: Pawel Kowalski Date: Thu, 16 Aug 2018 16:13:05 +0200 Subject: [PATCH 4/5] Move content blocks into content-blocks directory --- client/src/components/Chapter.vue | 2 +- client/src/components/ContentBlock.vue | 8 ++++---- client/src/components/{ => content-blocks}/ImageBlock.vue | 0 .../src/components/{ => content-blocks}/StudentEntry.vue | 0 client/src/components/{ => content-blocks}/Task.vue | 0 client/src/components/{ => content-blocks}/TextBlock.vue | 0 6 files changed, 5 insertions(+), 5 deletions(-) rename client/src/components/{ => content-blocks}/ImageBlock.vue (100%) rename client/src/components/{ => content-blocks}/StudentEntry.vue (100%) rename client/src/components/{ => content-blocks}/Task.vue (100%) rename client/src/components/{ => content-blocks}/TextBlock.vue (100%) diff --git a/client/src/components/Chapter.vue b/client/src/components/Chapter.vue index 1b3393b9..54bcfd4c 100644 --- a/client/src/components/Chapter.vue +++ b/client/src/components/Chapter.vue @@ -8,7 +8,7 @@