[2.0.0-beta1] SDC prop as a HTML string

Created on 25 July 2024, about 1 month ago
Updated 2 August 2024, about 1 month ago

Hi,

Thanks for working on this module! I'm getting the hang of it! I played around with building a SDC component as configure a paragraph type to display as a component using Layout Builder and UI Patterns Layout. My paragraph has a body field which is a HTML string, and when I pass this body field to a prop "body" in my SDC, this field is displayed as an encoded HTML string. I wonder how I can display it as HTML without encoding?

Thanks!

πŸ’¬ Support request
Status

Closed: works as designed

Version

2.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States sea2709 Texas

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @sea2709
  • Status changed to Postponed: needs info about 1 month ago
  • πŸ‡«πŸ‡·France pdureau Paris

    Hello Dang Tran,

    Thanks for your feedback. This is very valuable as this stage of the project.
    Markup must be passed as a renderable in a slot, instead of a prop.

    Can you share with us your component definition?

  • πŸ‡«πŸ‡·France pdureau Paris

    Also, how do you "pass" the body field ? By using a field formatter or by picking the raw value of a field property ?

  • πŸ‡ΊπŸ‡ΈUnited States sea2709 Texas

    Hi again,

    Here is what I did. I have a paragraph type "Call to action" and a Call to action SDC component, which has 3 props: heading, body and button, all of them are string. The paragraph "Call to action" has a heading field which is a formatted text field. I use Layout Builder to configure the default display for paragraph type "Call to action", by using the Call to action SDC component. I select "Token" for the heading source "[paragraph:field_heading:processed]".

    As a result, my paragraph heading is displaying as plain text. I did some debugging on this file https://git.drupalcode.org/project/ui_patterns/-/blob/2.0.x/src/Plugin/U...

    I think the function getPropValue(), we can replace "return $this->tokenManager->replacePlain($value, $token_data, ['clear' => TRUE]);" by "return $this->tokenManager->replace($value, $token_data, ['clear' => TRUE]);"

    So the prop return value can be a markup string.

  • Status changed to Active about 1 month ago
  • πŸ‡«πŸ‡·France pdureau Paris

    Thanks a lot. It seems the issue is in your component model.

    heading is a string prop, but you are injecting [paragraph:field_heading:processed] which is a renderable value:

     [
            '#type' => 'processed_text',
            '#text' => $text,
            '#format' => $item->format,
            '#filter_types_to_skip' => [],
            '#langcode' => $item->getLangcode(),
    ];

    https://api.drupal.org/api/drupal/core%21modules%21text%21src%21TextProc...

    So, it belongs to a slot, because:

    • No renderables (markup, render arrays, object implementing Renderable interface, list of renderables...) in props
    • Only renderables in slots (scalars get converted to #plain_text renderables

    Tokens types are not known before processing, so the source plugin will not do the check. We rely on the user to inject value of the expected type in the prop.

    However, there may be something to fix or improve with TokenSource plugin, I will investigate and host the potential MR in this issue.

  • πŸ‡ΊπŸ‡ΈUnited States sea2709 Texas

    I'm a little bit confused here. I think [paragraph:field_heading:processed] is a FilteredMarkup object

    If it is a FilteredMarkup object value, I think it's a valid value for prop?

  • πŸ‡«πŸ‡·France pdureau Paris

    I'm a little bit confused here. I think [paragraph:field_heading:processed] is a FilteredMarkup object

    If my understanding si right, [ '#type' => 'processed_text' ] render element is generating a FilteredMarkup.

    https://git.drupalcode.org/project/drupal/-/blob/11.x/core/modules/filte...

    If it is a FilteredMarkup object value, I think it's a valid value for prop?

    Injected in a string prop, this value will be rendered as a plain string, so with markup escaped.
    Why not using a slot instead ?

    Also, TokenSource is versatile and powerful, but there are maybe more suitable sources like "Data from field" where you can pick the field_heading field and the processed property, without using a token.

  • πŸ‡ΊπŸ‡ΈUnited States sea2709 Texas

    I agree using "Data from field" source is more appropriate in this case, and it works perfectly :-)

    I was just curious to do a testing on token source since I think it will be more powerful, but it can reach to cases where the component field should be slot.

  • πŸ‡ΊπŸ‡ΈUnited States sea2709 Texas

    I think in my case, setting up the heading as a prop seems right. It's just a string for a CTA heading. The client would like to emphasize some words in the heading, that's why I use a markup string for this case.

  • Status changed to Closed: works as designed about 1 month ago
  • πŸ‡«πŸ‡·France pdureau Paris

    I am glad it works :)

Production build 0.71.5 2024