wagtail_hooks.py

import wagtail.admin.rich_text.editors.draftail.features as draftail_features
from wagtail.admin.rich_text.converters.html_to_contentstate import (
    InlineStyleElementHandler
)
from wagtail.core import hooks


@hooks.register("register_rich_text_features")
def register_code_styling(features):
    """Add the <code> to the richtext editor."""

    # Step 1
    feature_name = "code"
    type_ = "CODE"
    tag = "code"

    # Step 2
    control = {
        "type": type_,
        "label": "</>",
        "description": "Code"
    }

    # Step 3
    features.register_editor_plugin(
        "draftail", feature_name, draftail_features.InlineStyleFeature(control)
    )

    # Step 4
    db_conversion = {
        "from_database_format": {tag: InlineStyleElementHandler(type_)},
        "to_database_format": {"style_map": {type_: {"element": tag}}},
    }

    # Step 5
    features.register_converter_rule("contentstate", feature_name, db_conversion)

    # Step 6 optional
    # This will register this feature with all richtext editors by default
    features.default_features.append(feature_name)


@hooks.register("register_rich_text_features")
def register_centertext_feature(features):
    """Creates centered text in our richtext"""

    feature_name = "center"
    type_ = "CENTERTEXT"
    tag = "div"

    control = {
        "type": type_,
        "label": "Center", # 라벨
        "description": "Center Text", # 설명
        "style": { # css
            "display": "block",
            "text-align": "center",
        },
    }

    features.register_editor_plugin(
        "draftail", feature_name, draftail_features.InlineStyleFeature(control)
    )

    db_conversion = {
        "from_database_format": {tag: InlineStyleElementHandler(type_)},
        "to_database_format": {
            "style_map": {
                type_: {
                    "element": tag,
                    "props": {
                        "class": "d-block text-center",
                    }
                }
            }
        },
    }

    features.register_converter_rule("contentstate", feature_name, db_conversion)

    features.default_features.append(feature_name)

control의 style은 Admin Page에서 보이는 RichEditor, db_conversion의 props는 Front-end 단계의 Style

'Back-End > Wagtail, Django' 카테고리의 다른 글

Wagtail Cache  (0) 2021.11.28
Wagtail Recaptcha  (0) 2021.11.28
Wagtail API v2 Serializing Rich Text  (0) 2021.11.25
Wagtail API v2 Serializing a QuerySet  (0) 2021.11.25
Wagtail API v2 Custom Page Properties  (0) 2021.11.25
from wagtail.core.templatetags.wagtailcore_tags import richtext

class RichtextBlock(blocks.RichTextBlock):
    """Richtext without (limited) all the features"""
    
    def get_api_representation(self, value, context=None):
        return richtext(value.source)
    
    class Meta: # noqa
        template = "streams/richtext_block.html"
        icon = "doc-full"
        label = "Full RichText"

 

'Back-End > Wagtail, Django' 카테고리의 다른 글

Wagtail Recaptcha  (0) 2021.11.28
Wagtail Rich Editor Extend  (0) 2021.11.27
Wagtail API v2 Serializing a QuerySet  (0) 2021.11.25
Wagtail API v2 Custom Page Properties  (0) 2021.11.25
Wagtail API v2 Image Rendition Field  (0) 2021.11.24
class BlogChildPagesSerializer(Field):
    def to_representation(self, child_pages):
        # logic in h
        # return_posts = []
        # for child in child_pages:
        #     post_dict = {
        #         'id': child.id,
        #         'title': child.title,
        #         'slug': child.slug,
        #         'url': child.url,
        #     }
        #     return_posts.append(post_dict)
            
        # return return_posts
        return [
            {
                'id': child.id,
                'title': child.title,
                'slug': child.slug,
                'url': child.url,
            } for child in child_pages
        ]


class BlogListingPage(Page):

	...
    
    api_fields = [
        APIField("get_child_pages", serializer=BlogChildPagesSerializer()),
    ]
    
    @property
    def get_child_pages(self):
        return self.get_children().public().live()

기존 class에 없던 데이터나 정보를 API Server에 전달하고 싶을 때에는 Serializer를 사용한다. 다만 단순히 Wagtail의 QuerySet을 전달하면 JSON형식의 데이터가 아니라서 API Server에서 오류가 난다. 

 

그래서 Serializer에서 JSON형식의 데이터를 전달해주기 위해 데이터를 가공을 해줘야한다. 

 

다만, 이미 property에서 field set을 선택하여 return 한다면 Serializer는 필요없다. 

간단한 데이터를 전달할 것이면 아래와 같은 방법으로 전달해도 된다. 

 

class BlogListingPage(Page):
  
    api_fields = [
        APIField("get_child_pages"),
    ]
    
    @property
    def get_child_pages(self):
        return self.get_children().public().live().values("id", "title", "slug")

 

 

추가)

api_fields = [
	APIField("posts", serializer=BlogChildPagesSerializer(source='get_child_pages')),
]

만약에 API Server에 posts라는 이름으로 데이터를 표시하고 싶다면 위와 같이 작성하면 된다. 

'Back-End > Wagtail, Django' 카테고리의 다른 글

Wagtail Rich Editor Extend  (0) 2021.11.27
Wagtail API v2 Serializing Rich Text  (0) 2021.11.25
Wagtail API v2 Custom Page Properties  (0) 2021.11.25
Wagtail API v2 Image Rendition Field  (0) 2021.11.24
Wagtail API v2 Serializers  (0) 2021.11.24
    api_fields = [
    	APIField('a_custom_api_response'),
    ]
    
    @property
    def a_custom_api_response(self):
        #return ["SOMETHING CUSTOM", 3.14, [1, 2, 3, 'a', 'b', 'c']]
        return f"Banner Title Is: {self.banner_title}"

@property를 통해 필요한 Logic이나 정보를 API 서버에 전달할 수 있다. 

저번 포스트에서 Serializer을 통해 Django Models의 이미지를 API서버로 표시하는 방법에 대해서 알아봤다. 

하지만 이미 Wagtail에서는 ImageRenditionField라는 것이 있어 Django Model의 Image를 간단하게 API서버에 

표시할 수 있다. 

 

 

1. Models.py

 

    from wagtail.images.api.fields import ImageRenditionField
    
    
    api_fields = [
        APIField(
            'image', 
            serializer=ImageRenditionField(
                'fill-200x250',                    
                source="author_image"
            )
        ),
    ]

사용 방법은 간단하다. "image"는 API Field에서 보여질 이름이다. 

Django Models의 image field에 API를 적용하여 확인해보면 다음과 같은 오류가 발생한다. 

이럴 때, API에 관련 Field의 정보를 Custom해서 표시해줄 수 있는 Serializer가 필요하다. 

 

from rest_framework.fields import Field


class ImageSerializedField(Field):
    
    def to_representation(self, value):
        return {
            "url": value.file.url,
            "title": value.title,
            "width": value.width,
            "height": value.height,
        }
        
        
class BlogAuthorsOrderable(Orderable):
    
    page = ParentalKey("blog.BlogDetailPage", related_name="blog_authors")
    author = models.ForeignKey(
        "blog.BlogAuthor",
        on_delete=models.CASCADE,
    )
    
    panels = [
        SnippetChooserPanel("author"),
    ]
    
    @property
    def author_image(self):
        return self.author.image
    
    api_fields = [
        APIField('author_image', serializer=ImageSerializedField()),
    ]

Django rest_framework모듈에서 Field을 상속받아서 Serializer를 만든다. 

def to_representation(self, value):

에서의 value는 APIField의 field 값. 즉, 'author_image'(=author.image)를 가르킨다.

 

 

추가)

class BannerCTASerializer(Field):
    def to_representation(self, page):
        return {
            'id': page.id,
            'title': page.title,
            'first_published_at': page.first_published_at,
            'owner': page.owner.username,
            'slug': page.slug,
            'url': page.url,
        }


class HomePage(page):

  api_fields = [
      APIField('banner_cta', serializer=BannerCTASerializer()), 
  ]

Serializer에는 API에 필요한 모든 Logic을 추가할 수 있다.

+ Recent posts