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 #2441811: Upgrade filter system to HTML5. 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

Issue fork drupal-3454196

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

james.williams created an issue. See original summary.

james.williams’s picture

Version: 10.2.x-dev » 11.0.x-dev

Switching to target Drupal 11.

james.williams’s picture

Issue summary: View changes
Status: Active » Needs review

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.

smustgrave’s picture

Status: Needs review » Needs work
Issue tags: +Needs Review Queue Initiative

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.

james.williams’s picture

Status: Needs work » Needs review

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!

james.williams’s picture

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!

james.williams’s picture

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

longwave’s picture

Thanks for reporting. I was entirely unaware of this in the filter system when I worked on the HTML5 parser upgrade, and so it only works as far as we have test coverage, and we've obviously missing test coverage for this case.

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. But not sure if the placeholder system will need wider work to handle this.

longwave’s picture

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>';
longwave’s picture

Version: 11.0.x-dev » 11.x-dev
Issue tags: -Needs Review Queue Initiative

Pushed a change for #11.

james.williams’s picture

Issue summary: View changes
Status: Needs review » Reviewed & tested by the community

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 ;-)

longwave’s picture

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.

longwave’s picture

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

quietone’s picture

Issue tags: +Needs followup

I read the IS, comments and MR. There are no outstanding questions and I had no recommendations to make on the MR. Leaving at RTBC

Added tag for a followup for #15.

  • larowlan committed 883e240e on 10.3.x
    Issue #3454196 by james.williams, longwave: Filter placeholders without...

  • larowlan committed f3d8334b on 10.4.x
    Issue #3454196 by james.williams, longwave: Filter placeholders without...

  • larowlan committed c1976a98 on 11.0.x
    Issue #3454196 by james.williams, longwave: Filter placeholders without...

  • larowlan committed dc89b84c on 11.x
    Issue #3454196 by james.williams, longwave: Filter placeholders without...
larowlan’s picture

Version: 11.x-dev » 10.3.x-dev
Status: Reviewed & tested by the community » Fixed
Issue tags: +Bug Smash Initiative

Committed to 11.x and backported to 11.0.x, 10.4.x and 10.3.x

Thanks folks

james.williams’s picture

Woah, thank you!

longwave’s picture

Issue tags: -Needs followup

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

wim leers’s picture