Problem/Motivation

For the Configurable Help Topic system (see #2351991: Add a config entity for a configurable, topic-based help system and my sandbox project https://www.drupal.org/sandbox/jhodgdon/2369943 which is developing it), I need a way for a config entity to have a "Body" field containing formatted text.

The obvious way to do this is just to put the "body" into one big HTML string, but this is problematic. The main reason is that strings on config entities get translated (on localize.drupal.org if they are provided in Core), and having large translated strings with HTML tags in them poses problems:
- Translations get invalidated if any part is changed. So it is better if the strings are shorter rather than the entire text of the "body", so that if one sentence changes, only one shorter string is invalidated.
- Long strings take longer to translate and review for translators, and are harder to get right (one error in one place means it can get rejected).
- It is difficult for the translators to get all the HTML tags right. They can get corrupted or become unmatched.

So, rather than having one big string with HTML embedded in it, it is preferable to have shorter strings that are about a paragraph in length or so, and preferably without the HTML tags.

Besides config entities, it would also be desirable to use this for hook_help() implementations, which currently do things like:

$output .= '<p>' . t(something) . '</p>';
return $output;

which removes the HTML tags and shortens the strings, but is ugly. You cannot even do that that in a config entity, though -- you need some kind of a system for splitting up the string and abstracting out the HTML tags.

Proposed resolution

Related issue #2697791: Add Plugin system for abstracted HTML-formatted text is exploring a plugin system to do this.

On this issue, the idea is to use some type of markdown format. We would need to do the following to get this done:

a) Choose a particular flavor of markdown. On #2697791-3: Add Plugin system for abstracted HTML-formatted text, bojanz suggested Commonmark; however it currently lacks a way to do definition-style lists (DL/DT/DD in HTML terms -- which you could do by embedding the HTML tags directly, but that kind of defeats the purpose of this whole idea if you have to include HTML tags to use these lists, which are very very very common in things like hook_help() and help topics in general).

b) Add a PHP library that can parse/render this markdown flavor to the vendor area of Core (as a composer dependency).

c) Document a way to separate a long string of (text + markdown) formatting into smaller strings for translatability. The idea would be similar to what is used in #2697791: Add Plugin system for abstracted HTML-formatted text : each "paragraph" or "section" of markdown-formatted text would be a separate string. Developers or config entity editors would choose how to split it up.

d) Figure out how to express this in a render array (define a render element etc.).

e) Figure out how to express this in a config entity schema/renderer (should be fairly simple).

Remaining tasks

a) Figure out all of the unknowns in the Proposed Resolution.

b) Convert a hook_help() implementation in Core to use this, as an illustration of how much nicer it is than returning HTML strings.

c) Make a patch.

d) Try using this for the Configurable Help config entity and verify it is workable for the UI and config schema, as a viable replacement for the "text sections" plugin system and element of #2697791: Add Plugin system for abstracted HTML-formatted text.

e) Write a change notice for the new stuff.

f) Decide on #2697791: Add Plugin system for abstracted HTML-formatted text vs. this issue (which one is better), and get one of them committed to Core.

User interface changes

None.

API changes

API addition: New markdown render element and library added to vendor area. No API changes.

Data model changes

No.

Comments

jhodgdon created an issue. See original summary.

jhodgdon’s picture

Assigned: jhodgdon » Unassigned
Status: Needs review » Active

Whoops, I guess you get all the issue metadata when you clone an issue. ;)

bojanz’s picture

c) Figure out a way to separate a long string of (text + markdown) formatting into smaller strings for translatability.

Same way as in the plugin approach, by having the config entity field have multiple values/paragraphs.

jhodgdon’s picture

Ah, so you mean you would have the admin/user edit the "body" as one big text field, and then upon save, separate at paragraph breaks (probably defined as two newlines in a row), or something like that?

Or would you give them separate "body paragraph" items, with an "Add new paragraph" button, the way I did in Configurable Help with the "sections"? (This is working in my sandbox module referenced in the issue summary -- each section the admin/editor chooses the section type, like header, paragraph, or bullet item, and then has a text field to put the text in, with a standard Drupal text format.)

bojanz’s picture

Or would you give them separate "body paragraph" items, with an "Add new paragraph" button, the way I did in Configurable Help with the "sections"?

This, individual sections, except you don't need a section type cause it's all markdown.

jhodgdon’s picture

Issue summary: View changes

OK, good. Adding this idea to the issue summary.

jhodgdon’s picture

Issue summary: View changes

Whoops, wrong issue links in several places in the summary.

jhodgdon’s picture

Any comments on the merits of this approach vs. #2697791: Add Plugin system for abstracted HTML-formatted text?

jhodgdon’s picture

So one thing that occurs to me with this approach... Let's say I'm editing a help page using this, and I am defining a bullet list. My "chunks" might look like:

a)

* First bullet item

b)

* Second bullet item, which could be much longer

etc.

Then you might have a numbered list, which depending on the flavor of markdown being used, might look like:

c)

# First numbered item

or

. Second numbered item

or whatever the formatting code for numbered list is.

So... The problem is that the translator has to get the formatting code right. Depending on the markdown flavor, this might include a character that isn't recognized unless it is in the correct position in the line (all the way left, indented, etc.). Or they might need to have the correct number of === signs in a row to get the header level right. Etc. So, it puts the responsibility back on the translator to get the formatting stuff right. They aren't doing HTML tags at least, and Markdown formatting stuff is probably easier, but it still could be a problem.

With the plugin approach being discussed on #2697791: Add Plugin system for abstracted HTML-formatted text, the "what type of chunk is this" is taken out of the chunk itself. So that might be one point in favor of the other approach.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.