Filter placeholders without arguments are not replaced when HTML corrector filter applied afterwards

Created on 12 June 2024, 20 days ago
Updated 26 June 2024, 6 days ago

Problem/Motivation

When a filter that uses a placeholder, without arguments, is configured in a text format, to run before the filter_htmlcorrector filter, the first filter's placeholder is not replaced on rendering the text. The drupal-filter-placeholder element remains.

A filter might use a placeholder without arguments simply to postpone rendering something that may be expensive to build. I haven't seen any examples in core, but I've come across a custom one before that builds a form in place of a custom token in text.

This is an issue since Drupal 10.2, which started using masterminds/html5 in πŸ› Upgrade filter system to HTML5 Fixed . I would guess it's still the same in later versions, though I haven't actually tested yet.

Steps to reproduce

  1. Configure a text format:
    1. Enable a filter that uses a placeholder without any arguments (I'm not aware of any in core, sorry).
    2. Enable core's 'Correct faulty and chopped off HTML' filter and ensure it runs after that.
  2. Make some content that uses that text format and which would cause that first filter's placeholder to be used.
  3. Expected result: the placeholder is replaced. Actual result: the drupal-filter-placeholder element remains.

Proposed resolution

Do not add the arguments attribute to the placeholder markup when it is empty, so that the placeholder does not get altered by the filter_htmlcorrector filter. (This would then match the behavior of \Drupal\Core\Render\PlaceholderGenerator::createPlaceholder().)

Remaining tasks

Review MR.

User interface changes

None.

API changes

None.

Data model changes

None.

Release notes snippet

πŸ› Bug report
Status

RTBC

Version

11.0 πŸ”₯

Component
FilterΒ  β†’

Last updated less than a minute ago

No maintainer
Created by

πŸ‡¬πŸ‡§United Kingdom james.williams

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

Merge Requests

Comments & Activities

  • Issue created by @james.williams
  • πŸ‡¬πŸ‡§United Kingdom james.williams

    Switching to target Drupal 11.

  • Pipeline finished with Failed
    20 days ago
    Total: 745s
    #197339
  • Pipeline finished with Success
    20 days ago
    Total: 928s
    #197359
  • Status changed to Needs review 20 days ago
  • πŸ‡¬πŸ‡§United Kingdom james.williams

    MR includes a fix and updated tests to demonstrate the issue. The tests without the fix fail as expected (although I'm surprised to see GitLab now shows that with a green tick! But the detailed output shows the failure), and with the fix they pass as expected.

  • Status changed to Needs work 13 days ago
  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Small super nitpicky change

    But MR should be pointed to 11.x vs 11.0.x as 11.x is still the "main" branch.

    I see the test-only feature passes when it should fail so tests seem to need some work.

    As far as your comment on the MR I also could not find a spot and we don't have a filter sub-maintainer so think it's fine for now.

  • Status changed to Needs review 12 days ago
  • πŸ‡¬πŸ‡§United Kingdom james.williams

    Thanks for the review. As I mentioned before, the detailed output in the log of the test-only feature shows there was a test failure. I don't know why the pipeline makes it look like it succeeded!

  • Pipeline finished with Success
    12 days ago
    Total: 800s
    #203518
  • πŸ‡¬πŸ‡§United Kingdom james.williams

    Ah @fjgarlin has helped clarify on slack that the tests-only feature showing as passed is a bug in core's test-only script. Please see from the detailed log that the test really does fail!

  • Pipeline finished with Canceled
    12 days ago
    Total: 407s
    #203571
  • Pipeline finished with Failed
    12 days ago
    Total: 510s
    #203583
  • Pipeline finished with Success
    12 days ago
    Total: 1074s
    #203592
  • πŸ‡¬πŸ‡§United Kingdom james.williams

    The fact that the tests-only run can 'pass' is handled in πŸ› Test-only job does not detect failures correctly Needs review (which I'm having a go at progressing). I'm including the change from there here for now, as advised by @fjgarlin there.

  • Pipeline finished with Success
    12 days ago
    Total: 650s
    #203616
  • Pipeline finished with Success
    12 days ago
    Total: 1039s
    #203635
  • πŸ‡¬πŸ‡§United Kingdom longwave UK

    If there are no arguments, would it be better/more correct to not output the arguments attribute at all? ie. we would just have <drupal-filter-placeholder callback="callback" token="token" />? Then, the HTML5 parser/emitter does not need to special case this at all.

  • πŸ‡¬πŸ‡§United Kingdom longwave UK

    In PlaceholderGenerator we did update it to optionally output the arguments for HTML5, so I do think we should try the same here:

        $placeholder_markup = '<drupal-render-placeholder callback="' . Html::escape($callback) . '"';
        if ($arguments !== '') {
          $placeholder_markup .= ' arguments="' . Html::escape($arguments) . '"';
        }
        $placeholder_markup .= ' token="' . Html::escape($token) . '"></drupal-render-placeholder>';
    
  • πŸ‡¬πŸ‡§United Kingdom longwave UK

    Pushed a change for #11.

  • Pipeline finished with Success
    6 days ago
    Total: 538s
    #208555
  • Status changed to RTBC 6 days ago
  • πŸ‡¬πŸ‡§United Kingdom james.williams

    Oh nice idea, thank you! Yes, I'm on board with that, I've tested my case manually too just to check, and it works fine. Combined with the automated test, I trust it's OK to put this to RTBC based on that.

    If I were being really nitpicky, I'd suggest we check Html::escape($arguments) !== '', since it's the escaped version that gets used, but I see we're just doing the same as in PlaceholderGenerator::createPlaceholder(). So if that nitpick even mattered, we could just change both in a follow-up. But I'm not being nitpicky, so ignore that thought ;-)

  • πŸ‡¬πŸ‡§United Kingdom longwave UK

    I think in a followup we could even refactor that code into a static helper method on PlaceholderGenerator, so all placeholders are constructed in a consistent way.

  • πŸ‡¬πŸ‡§United Kingdom longwave UK

    Mistakenly removed the original tag when working on this at Dev Days.

Production build 0.69.0 2024