Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow defining translatable_fields/override_translatable_fields on StructBlock #752

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

freddiemixell
Copy link

@freddiemixell freddiemixell commented Dec 18, 2023

This PR is attempting to allow users to mark certain sub-blocks of a struct block to be ignored like UrlBlock.

Example use case:
blocks.py

class RichTextBlock(blocks.StructBlock):
    """Rich text block."""

    rich = blocks.RichTextBlock(
        required=True,
        help_text="Add a rich text context",
        features=['h2', 'h3', 'h4', 'h5', 'h6', 'bold', 'italic', 'link', 'ol', 'ul', 'hr', 'superscript', 'subscript', 'strikethrough', 'blockquote', 'code'],
    )
   
class CustomImageBlock(blocks.StructBlock):
    """Banner image block."""

    image = ImageChooserBlock(required=True, help_text="Add a banner image.")
    description = blocks.TextBlock(required=False, help_text="Add a description for the image.")
    
    override_translatable_blocks = [
        "description"
    ]

class YouTubeBlock(blocks.StructBlock):
    """YT Video block."""

    video_id = blocks.CharBlock(
        required=True,
        help_text="Add a YouTube video ID"
    )

    override_translatable_blocks = []
    
class CodeBlock(blocks.StructBlock):
    """Code block."""

    code = blocks.TextBlock(required=True, help_text="Add your code snippet here.")
    language = blocks.ChoiceBlock(choices=[
        ('python', 'Python'),
        ('javascript', 'JavaScript'),
        ('java', 'Java'),
        ('c', 'C'),
    ], required=True, help_text="Select the language of your code snippet.")

    override_translatable_blocks = []

In the above example the first block doesn't define the property so it goes through the code the same as before.

The second block only includes the description field, which technically doesn't matter because the image would be skipped regardless. However, I added it in to illustrate how you could exclude fields by simply not adding them to the list.

The last 2 examples we add the property but with an empty list. That will prevent any blocks from this struct block from being extracted.

Notes:
Closes #307

@codecov-commenter
Copy link

codecov-commenter commented Dec 18, 2023

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (a3efa8f) 92.60% compared to head (5fb32e5) 92.65%.
Report is 13 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #752      +/-   ##
==========================================
+ Coverage   92.60%   92.65%   +0.05%     
==========================================
  Files          46       47       +1     
  Lines        4017     4072      +55     
  Branches      598      603       +5     
==========================================
+ Hits         3720     3773      +53     
- Misses        175      176       +1     
- Partials      122      123       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@zerolab
Copy link
Collaborator

zerolab commented Dec 20, 2023

Thank you @freddiemixell. Could you please add some tests?

@freddiemixell
Copy link
Author

No problem! I begin working on them already but alas the work week came and stole me away lol

I will have some time starting this weekend and I'm off all next week so I will wrap this up then if I don't find during the week.

@freddiemixell
Copy link
Author

@zerolab I figured out some intial tests. Let me know if you'd like more or any changes.

Happy holidays! ☃️

Copy link
Collaborator

@zerolab zerolab left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a solid start @freddiemixell

Can you update

!!! attention
It is not currently possible to configure `StructBlock` translatable fields. See [Issue #307](https://github.com/wagtail/wagtail-localize/issues/307) for more details.
and remove the notices, as well as add a section at the end on how to use this?

Aside from that, I keep going back to the fact that for regular models we allow defining whether a field is translatable or is synchronised, and that we need to support this for StructBlocks.
For example, in your CustomImageBlock we want the description to be translatable, but the image to be synchronised. I am making an assumption here as I am not fully geared to test things locally ('tis Christmas after all), but what happens in that case?

wagtail_localize/segments/extract.py Outdated Show resolved Hide resolved
@freddiemixell
Copy link
Author

This is a solid start @freddiemixell

Can you update

!!! attention
It is not currently possible to configure `StructBlock` translatable fields. See [Issue #307](https://github.com/wagtail/wagtail-localize/issues/307) for more details.

and remove the notices, as well as add a section at the end on how to use this?
Aside from that, I keep going back to the fact that for regular models we allow defining whether a field is translatable or is synchronised, and that we need to support this for StructBlocks. For example, in your CustomImageBlock we want the description to be translatable, but the image to be synchronised. I am making an assumption here as I am not fully geared to test things locally ('tis Christmas after all), but what happens in that case?

Hey @zerolab,

Thanks for checking this out on Christmas! (Tis Christmas made me lol)

I see what you're saying about the image block and synchronization. I'll investigate if this will cause any issues with synchronized fields today.

If you have any specific tests you're thinking of let me know and I'll try to hook it up, thanks again!

@freddiemixell
Copy link
Author

How I'm Testing

  • Go to english source page.
  • Click "Sync translated pages" but don't publish.
  • Go to french version of the page to inspect what is in the UI.
  • Publish the french version and screen shot the frontend results.
  • Go back to the english version and screenshot to make sure nothing is changing.

How the source test post is structured:

sourceadmin

Scenario 1: Testing ignoring the description struct field

StructBlock:

  • image = ImageChooserBlock
  • description = CharBlock
  • translatable_blocks = []

Expected:

  • image block still available to override
  • description block not showing

Result:

  • image block still available to override
  • description block not showing

English Page
1EN

French Page
1FR


Scenario 2: Testing explicitly telling it description should be translated

StructBlock:

  • image = ImageChooserBlock
  • description = CharBlock
  • translatable_blocks = ['description']

Expected:

  • image block still available to override
  • description available to translate
  • note: this should be the same as doing nothing, scenario 3.

Result:

  • image block still available to override
  • description available to translate

English Page
2EN

French Page
2FR


Scenario 3: Testing default/backwards compatibility

StructBlock:

  • image = ImageChooserBlock
  • description = CharBlock

Expected:

  • image block still available to override
  • description available to translate

Result:

  • image block still available to override
  • description available to translate

English Page
3EN

French Page
3FR

@freddiemixell
Copy link
Author

I'll add that I'm not sure why exactly this is working with the images. That is what I'm going to work on figuring out now so I could really get behind this or find any flaws.

@freddiemixell
Copy link
Author

freddiemixell commented Jan 4, 2024

Issue:

When overriding the image of the youtube button in the french version with a picture of the Eiffel Tower I still see the Youtube button.

I believe this means it's breaking the overridable segments somehow.

Update:

I reverted this change a second time, reset everything and now I do see the image block going through so this seems like a problem with this PR still.

Whats actually happening:
After testing this a bit further I'm seeing that I was mistaken before. I was getting confused because I had an image field on my blog model and I was mistaking that for the image block. I changed it to another image and that revealed the issue.

translatable_blocks = ['description']

This prevents the images from being overridden, which is sort of enforced by this configuration if you wanted to prevent images from being changed for some reason.

translatable_blocks = ['image']

However, this configuration produces a different scenario where you can keep the same text but allow overriding the image. When I did this I was able to override the image successfully in the French version. Which means this isn't technically a bug but does allow for a little more control over nested images if you need it.


## Specifying Translatable Fields within a StructBlock

**By default, all sub-fields within a StructBlock are included for translation.** However, there may be instances where certain fields within the StructBlock should be excluded from translation. To facilitate this, we've introduced the **`translatable_blocks`** parameter.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: no need to wrap inline code ** (bold)


## Specifying Translatable Fields within a StructBlock

**By default, all sub-fields within a StructBlock are included for translation.** However, there may be instances where certain fields within the StructBlock should be excluded from translation. To facilitate this, we've introduced the **`translatable_blocks`** parameter.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: wrap StructBlock, CharBlock, TextBlock and YouTubeBlock in backticks (so they are treated as inline code)


##### Managing Images and Overrideable Segments within a StructBlock

When dealing with overrideable segments such as images within a StructBlock, it's important to note that ignoring these segments could result in losing the ability to use a different image for different languages. If you want to maintain the ability to override an image, include it in the list of translatable_blocks to preserve the default behavior.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion:

Suggested change
When dealing with overrideable segments such as images within a StructBlock, it's important to note that ignoring these segments could result in losing the ability to use a different image for different languages. If you want to maintain the ability to override an image, include it in the list of translatable_blocks to preserve the default behavior.
It is important to note that ignoring overrideable segments such as images within a `StructBlock` could result in losing the ability to use a different image for different languages. If you want to maintain the ability to override an image, include it in the list of `translatable_blocks` to preserve the default behavior.

translatable_blocks = ["caption", "image"]
```

In this example, the image is still overrideable, but the address, which is unique to this location, is locked in by translatable_blocks. This allows you to maintain the flexibility of using different images for different languages, while ensuring that certain unique information remains consistent across all translations.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
In this example, the image is still overrideable, but the address, which is unique to this location, is locked in by translatable_blocks. This allows you to maintain the flexibility of using different images for different languages, while ensuring that certain unique information remains consistent across all translations.
In this example, the image is still overrideable. The address, nique to this location, is locked in by `translatable_blocks`. This allows you to maintain the flexibility of using different images for different languages, while ensuring that certain unique information remains consistent across all translations.

@zerolab
Copy link
Collaborator

zerolab commented Jan 4, 2024

@freddiemixell the code tests should pretty much follow what you test as a user, manually

@zerolab
Copy link
Collaborator

zerolab commented Feb 6, 2024

Hey @freddiemixell do you need any help / pointers on tests?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow defining translatable_fields/override_translatable_fields on StructBlock
3 participants