最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

headless cms - Applying CSS classes to RichTextblock in wagtails StreamField API Response - Stack Overflow

programmeradmin4浏览0评论

I am using wagtail in headless mode with tailwind/nextjs.
When i add RichTextBlock and choose h2, In API response we get data as :

{
    "type": "text",
    "value": "<h2 data-block-key=\"owi81\">Repurpose Article into Social Media Content</h2>",
    "id": "2b7e811d-eb1b-40da-b108-8cf9778536b3"
}

I wish to be able to use tailwind classes so output could be:

{
    "type": "text",
    "value": "<h2 data-block-key=\"owi81\" class=\"text-5xl\"></h2>",
    "id": "2b7e811d-eb1b-40da-b108-8cf9778536b3"
}

I tried wagtail hooks but couldn't really make things work!

@hooks.register('register_rich_text_features')
def register_tailwind_classes(features):
   feature_name = 'h2'
   type_ = 'header-two'
   tag = 'h2'

   # 4.configure the content transform from the DB to the editor and back.
   db_conversion = {
       'from_database_format': {tag: TailwindClassHandler(type_)},
       'to_database_format': {'block_map': {type_: tag}},
   }

   # 5. Call register_converter_rule to register the content transformation conversion.
   features.register_converter_rule('contentstate', feature_name, db_conversion)

How can we achieve this?
Is it even the right way!

I am using wagtail in headless mode with tailwind/nextjs.
When i add RichTextBlock and choose h2, In API response we get data as :

{
    "type": "text",
    "value": "<h2 data-block-key=\"owi81\">Repurpose Article into Social Media Content</h2>",
    "id": "2b7e811d-eb1b-40da-b108-8cf9778536b3"
}

I wish to be able to use tailwind classes so output could be:

{
    "type": "text",
    "value": "<h2 data-block-key=\"owi81\" class=\"text-5xl\"></h2>",
    "id": "2b7e811d-eb1b-40da-b108-8cf9778536b3"
}

I tried wagtail hooks but couldn't really make things work!

@hooks.register('register_rich_text_features')
def register_tailwind_classes(features):
   feature_name = 'h2'
   type_ = 'header-two'
   tag = 'h2'

   # 4.configure the content transform from the DB to the editor and back.
   db_conversion = {
       'from_database_format': {tag: TailwindClassHandler(type_)},
       'to_database_format': {'block_map': {type_: tag}},
   }

   # 5. Call register_converter_rule to register the content transformation conversion.
   features.register_converter_rule('contentstate', feature_name, db_conversion)

How can we achieve this?
Is it even the right way!

Share Improve this question asked Feb 16 at 18:58 ArunArun 8861 gold badge13 silver badges19 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 1

I prefer to keep headings as their own block with an extra field to provide an optional anchor target.

If you do keep it in the rich text block, I would drop the built-in H2 format and create a custom one that adds the css class to the output. This is done in the features.register_converter_rule() method.

I use the following to register block features in Draftail:

def register_block_feature(
    features,
    feature_name,
    type_,
    description,
    css_class,
    element="div",
    wrapper=None,
    label=None,
    icon=None,
    editor_style=None,
):
    control = {
        "type": type_,
        "description": description,
        "element": element,
    }
    if label:
        control["label"] = label
    elif icon:
        control["icon"] = icon
    else:
        control["label"] = description
    if editor_style:
        control["style"] = editor_style

    features.register_editor_plugin(
        "draftail",
        feature_name,
        draftail_features.BlockFeature(control, css={"all": ["draftail-editor.css"]}),
    )

    block_map = {"element": element, "props": {"class": css_class}}
    if wrapper:
        block_map["wrapper"] = wrapper

    features.register_converter_rule(
        "contentstate",
        feature_name,
        {
            "from_database_format": {
                f"{element}[class={css_class}]": BlockElementHandler(type_)
            },
            "to_database_format": {
                "block_map": {
                    type_: block_map
                }
            },
        },
    )

Then your hook would be something like:

@hooks.register('register_rich_text_features')
def register_tailwind_h2_feature(features):
    register_block_feature(
        features=features,
        feature_name='tw-h2',
        type_='tw-h2',
        description='H2',
        css_class='text-5xl',
        element='h2',
        icon='h2'
    )

Finally, in your editor feature list, swap h2 for tw-h2. There's more info on this topic in these articles.

The one drawback on this is that you lose the markdown support for h2 (by typing ##) - the draftail docs lack any information on registering/modifying keyboard and markdown shortcuts unfortunately. I'd like to find out info on this if anyone has it.

Instead of using heading elements within the rich text block, give them their own block type in the StreamField definition:

body = StreamField([
    ("paragraph", blocks.RichTextBlock()),
    ("heading", blocks.CharBlock()),
    # ... other blocks
])

That way, you can define exactly what markup to give to the heading within your client-side code, instead of having to fiddle with the API response to include presentational class attributes. (After all, the whole reason you chose to use Wagtail in headless mode was to keep presentational logic fully on the client side, presumably...?)

发布评论

评论列表(0)

  1. 暂无评论