Problem/Motivation

Part of #2549943: [plan] Remove as much of the SafeMarkup class's methods as possible. The only use of drupal_placeholder() and SafeMarkup::placeholder() in core are wrong. They are basically using it to wrap with em tags.

Proposed resolution

Remove SafeMarkup::placeholder(), deprecate drupal_placeholder() and stop drupal_placeholder() from marking safe.

Remaining tasks

  • Agree
  • Patch
  • Commit

User interface changes

None

API changes

  • Remove SafeMarkup::placeholder()
  • Deprecate drupal_placeholder()
  • Don't mark output drupal_placeholder() of safe

Data model changes

None

Comments

alexpott created an issue. See original summary.

alexpott’s picture

Status: Active » Needs review
StatusFileSize
new12.11 KB
catch’s picture

Just nits, looks lovely.

  1. +++ b/core/includes/bootstrap.inc
    @@ -950,10 +951,13 @@ function drupal_static_reset($name = NULL) {
    + *   therefore has few valid use-cases. Note also, that this method does mark
    

    'does not' isn't it?

    Are there any valid use cases?

  2. +++ b/core/modules/editor/editor.module
    @@ -78,7 +78,7 @@ function editor_form_filter_admin_overview_alter(&$form, FormStateInterface $for
    -    $editor_name = ($editor && isset($editors[$editor->getEditor()])) ? $editors[$editor->getEditor()]['label'] : drupal_placeholder('—');
    

    So just no <em> tags here?

dawehner’s picture

+++ b/core/modules/filter/src/FilterPermissions.php
@@ -60,7 +60,11 @@ public function permissions() {
+            '#prefix' => '<em>',
+            '#markup' => $this->t('Warning: This permission may have security implications depending on how the text format is configured.'),
+            '#suffix' => '</em>'

+++ b/core/modules/node/src/Controller/NodeController.php
@@ -205,7 +205,11 @@ public function revisionOverview(NodeInterface $node) {
+            'prefix' => '<em>',
+            '#markup' => $this->t('current revision'),
+            'suffix' => '</em>',

+++ b/core/modules/update/update.report.inc
@@ -242,7 +243,7 @@ function template_preprocess_update_project_status(&$variables) {
-      $extra_item['data'] = drupal_placeholder($value['data']);
+      $extra_item['data'] = ['prefix' => '<em>', '#markup' => $value['data'], '#prefix' => '</em>'];

Did the 'class="placeholder"' added better accessibility?

alexpott’s picture

StatusFileSize
new1.1 KB
new12.3 KB

@dawehner I'm not sure how the placeholder class is more accessible?

@catch thanks for the review.
1. Yep it does not. Also I've improved the docs to point to SafeMarkup::format().
2. Yep no <em> - why to why need emphasis of a dash?

stefan.r’s picture

  • +++ b/core/modules/update/update.report.inc
    @@ -266,13 +267,10 @@ function template_preprocess_update_project_status(&$variables) {
    +        $base_themes[] = $base_theme . " ($base_status_label)";
    

    Does $base_theme lose the emphasis here?

  • * - %variable: Escaped to HTML and formatted using self::placeholder()

    Not anymore :)

dawehner’s picture

Sadly #601548: Loosen the dependency between t() and the theming layer never had a justification for the class so yeah I think its totally fine to remove it.

alexpott’s picture

@stefan.r fix the docs.

+++ b/core/modules/update/templates/update-project-status.html.twig
@@ -109,7 +109,7 @@
+      Depends on: {{ basethemes|placeholder }}

This keeps the placeholder markup in the update report.

HEAD

PATCH

So yep the patch put more inside the <em> tag - but is that a bad thing - tbh I think the list of dependencies should not contain the update required text?

Ah!!!! This base theme stuff in the update report is legacy stuff. In D7 days base theme did not have to be enabled to this update report had to do special things. In D8 they do so this is all legacy.

alexpott’s picture

David_Rothstein’s picture

Sadly #601548: Loosen the dependency between t() and the theming layer never had a justification for the class so yeah I think its totally fine to remove it.

I think the justification is at #601548-7: Loosen the dependency between t() and the theming layer. But the cases that this patch removes it from look like they are probably all OK without it (seems good as long as it stays for actual translation placeholders).

+tr.fallback_format td {
+  font-style: italic;
+}

This doesn't look right since it's causing the whole row to be italicized (including things like the "Configure" button).

Also the addition of the fallback_format class is causing the drag and drop handler to disappear from that row. No idea why...

David_Rothstein’s picture

Also the addition of the fallback_format class is causing the drag and drop handler to disappear from that row. No idea why...

Oh I see, I think it's because FilterFormatListBuilder::buildRow() does this at the bottom:

    return $row + parent::buildRow($entity);

That is not going to merge things like $row['#attributes']['class'] correctly, so it winds up without the "draggable" class.

The last submitted patch, 2: 2552579.2.patch, failed testing.

The last submitted patch, 5: 2552579.4.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 8: 2552579.8.patch, failed testing.

Status: Needs work » Needs review

stefan.r queued 8: 2552579.8.patch for re-testing.

Status: Needs review » Needs work

The last submitted patch, 8: 2552579.8.patch, failed testing.

alexpott’s picture

Status: Needs work » Needs review
StatusFileSize
new3.26 KB
new13.16 KB

Fixed up the test fails.

@David_Rothstein yep I noticed that too - I asked @joelpittet on IRC about the best way to address it. But in lieu of an answer I think the best thing to do will be to just make the roles text italic for fallback formats since that actually makes semantic sense. That's what we actually want to emphasise.

joelpittet’s picture

Status: Needs review » Needs work
  1. +++ b/core/modules/editor/editor.module
    @@ -78,7 +78,7 @@ function editor_form_filter_admin_overview_alter(&$form, FormStateInterface $for
    -    $editor_name = ($editor && isset($editors[$editor->getEditor()])) ? $editors[$editor->getEditor()]['label'] : drupal_placeholder('—');
    +    $editor_name = ($editor && isset($editors[$editor->getEditor()])) ? $editors[$editor->getEditor()]['label'] : '—';
    

    +1 lol, I'm sure that made a difference in Arial or most sans-serifs.

  2. +++ b/core/modules/filter/src/FilterFormatListBuilder.php
    @@ -94,24 +95,24 @@ public function buildHeader() {
    -      $row['label'] = SafeMarkup::placeholder($entity->label());
    

    Label looks as though it needs a wrapper attribute class too.

  3. +++ b/core/modules/update/templates/update-project-status.html.twig
    @@ -109,7 +109,7 @@
    -      Depends on: {{ basethemes }}
    +      Depends on: {{ basethemes|placeholder }}
    
    +++ b/core/modules/update/update.report.inc
    @@ -266,13 +267,10 @@ function template_preprocess_update_project_status(&$variables) {
    -        $base_themes[] = t('%base_theme (!base_label)', array(
    ...
    -          '!base_label' => $base_status_label,
    

    This will wrap em around both the label and the base theme. So the end result won't be the same.

  4. +++ b/core/modules/update/update.report.inc
    @@ -5,6 +5,7 @@
    +use Drupal\Component\Utility\Html;
    
    @@ -242,7 +243,7 @@ function template_preprocess_update_project_status(&$variables) {
    +      $extra_item['data'] = ['#prefix' => '<em>', '#markup' => $value['data'], '#prefix' => '</em>'];
    

    Should the data still be escaped? or the new use statement not needed?

  5. +++ b/core/modules/user/src/Tests/UserValidationTest.php
    @@ -136,7 +136,7 @@ function testValidation() {
    -    $this->assertEqual($violations[0]->getMessage(), t('!name field is required.', array('!name' => SafeMarkup::placeholder($user->getFieldDefinition('mail')->getLabel()))));
    +    $this->assertEqual($violations[0]->getMessage(), t('%name field is required.', array('%name' => $user->getFieldDefinition('mail')->getLabel())));
    

    +1 Totally!

alexpott’s picture

@joelpittet thanks for the review:

  1. Indeed
  2. See #17 I actually think we only want to emphasise the description text in the roles comment.
  3. This is a silly distinction in HEAD plus all this code will be removed because it is obsolete see #2338167: Update ProjectInfo class to reflect changes to extension system
  4. I guess so. We should wait for #2549791: Remove SafeMarkup::xssFilter() and provide ability to define #markup escaping strategy and what tags to filter then.
  5. Indeed

The last submitted patch, 17: 2552579.17.patch, failed testing.

joelpittet’s picture

@alexpott #18.3 is silly how? it make a visual distinction between the two elements to me, there could be a better way to do that, but I don't think it's silly. Maybe those em tags could be moved into the template in a foreach loop instead of the join we are currently doing.

alexpott’s picture

Status: Needs work » Needs review
StatusFileSize
new2.39 KB
new13.61 KB

@joelpittet it is silly when you actually look at the output and image a theme that depended on multiple base themes then you'd have this italic non-italic thing going on for little gain in legibility or semantic meaning. But, anyway, as I pointed out this is moot this all of this now completely and utterly unnecessary since base themes have to be enabled. This only existed because in D7 they didn't have to be enabled.

The violation change is a bit interesting. The common form required text for translators is !name field is required. so I'm pretty sure the intention was to not make the translators have to translate yet another string. So we need to escape the field label and use the pass-through notation. Added a comment about this.

joelpittet’s picture

Status: Needs review » Needs work
Issue tags: +Needs screenshots

Ok let's get some screenshots on the bits that have changed markup:

  1. +++ b/core/modules/filter/src/FilterFormatListBuilder.php
    @@ -94,24 +95,24 @@ public function buildHeader() {
    +    $row['label'] = $this->getLabel($entity);
    ...
    -      $row['label'] = SafeMarkup::placeholder($entity->label());
    

    Filter Format List

  2. +++ b/core/modules/update/templates/update-project-status.html.twig
    @@ -109,7 +109,7 @@
         {% set basethemes = base_themes|join(', ') %}
    ...
    -      Depends on: {{ basethemes }}
    +      Depends on: {{ basethemes|placeholder }}
    

    Project status

And keep in mind that <em> may not be represented the same as <em class="placeholder"> as it has a purpose and should be taken into careful consideration if it's being removed, as it may be purposefully visually strengthened by it's CSS class.

alexpott’s picture

Status: Needs work » Needs review
StatusFileSize
new112.7 KB
new111.91 KB

Screenshots of the change to the update status report are in comment #8. Which will disappear anyway because this information is irrelevant now that base theme have to be installed.

And grepping the codebase for .placeholder in css shows that no of the places where it is used is affected by this change.

Filter screenshots:

HEAD

Patch

The screenshots for the filter listing page show how inappropriate the placeholder class is here - like why is the fallback placeholdered and the other not. The only reason is to mark the fallback format as something special. It has nothing to do with the placeholders. As stated about I think just emphasising the role text is enough because (a) this is not a role so it is different to the other values in this column (unlike the other columns) and (b) it is the special information that the table is trying to communicate is special.

joelpittet’s picture

I completely agree regarding the Filter Admin thank you for the screenshots on the Filter admin, those really help.

joelpittet’s picture

Also, confirm there is nothing in this patch that is affecting the .placeholder CSS

joelpittet’s picture

Still a bit unclear and not sure where the irreverence around the basethemes is found. It's not popping out of the patch for me as clear as it is to you.

alexpott’s picture

@joelpittet the irrelevance of base themes to the update status report is this. In D7 base themes didn't have to be installed so they would not have a regular project entry on the update status report. Now they do because they have to be installed. The special base theme and sub theme handling can be completely removed from the update status report, which is shown by the patch in #2338167: Update ProjectInfo class to reflect changes to extension system. A base theme is now just a regularly installed theme.

wim leers’s picture

Status: Needs review » Needs work
Issue tags: -Needs screenshots

Looks great! Found only one problem:

+++ b/core/modules/filter/src/FilterFormatListBuilder.php
@@ -140,6 +141,7 @@ public function getDefaultOperations(EntityInterface $entity) {
+    $form['#attached']['library'][] = 'filter/drupal.filter.admin';

This seems wrong? That library is solely for filter settings, not for a listing of formats.


Removed the Needs screenshots tag, #24 added screenshots.

alexpott’s picture

Status: Needs work » Needs review
StatusFileSize
new1.61 KB
new13.01 KB

@Wim Leers good point. Now we're only making the role description emphasised we don't actually need this. Given that we were wrapping this in SafeMarkup::placeholder() just using #prefix and #suffix does not represent a regression.

wim leers’s picture

Anonymous’s picture

Status: Needs review » Needs work
  1. +++ b/core/includes/bootstrap.inc
    @@ -950,10 +951,16 @@ function drupal_static_reset($name = NULL) {
    + * @deprecated in Drupal 8.0.0, will be removed before Drupal 9.0.0. Use
    + *   \Drupal\Component\Utility\SafeMarkup::format() and a %variable in
    + *   associative array of replacements to make instead. Note this this method
    + *   should not be used to only emphasise a string and therefore has few valid
    + *   use-cases. Note also, that this method does not mark the string as safe.
    

    This docblock left me a bit confused.
    - in "an" associative array
    - to make what?
    - "this this"
    - "few valid use-cases": the method is deprecated, so what valid use case is left? We should always implement an alternative, right?

  2. +++ b/core/modules/update/update.report.inc
    @@ -244,7 +245,7 @@ function template_preprocess_update_project_status(&$variables) {
    +      $extra_item['data'] = ['#prefix' => '<em>', '#markup' => $value['data'], '#prefix' => '</em>'];
    

    The 3rd element should probably be "#suffix".

alexpott’s picture

Status: Needs work » Needs review
StatusFileSize
new1.09 KB
new11.76 KB

Rerolled now #2338167: Update ProjectInfo class to reflect changes to extension system has landed.

Re #32

  1. Fixed the documentation. The alternative is SafeMarkup::format() with a %placeholder or the placeholder filter in Twig. tbh I'd remove the method but we're very close to RC
  2. All of this code have been removed by #2338167: Update ProjectInfo class to reflect changes to extension system
wim leers’s picture

Status: Needs review » Needs work
  1. +++ b/core/modules/update/update.report.inc
    @@ -228,7 +228,7 @@ function template_preprocess_update_project_status(&$variables) {
    +      $extra_item['data'] = ['#prefix' => '<em>', '#markup' => $value['data'], '#prefix' => '</em>'];
    

    Contrary to what #33.2 says, this still appears to be here?

  2. +++ b/core/includes/bootstrap.inc
    @@ -949,10 +949,11 @@ function drupal_static_reset($name = NULL) {
    + *   templates instead. Note this method should not be used to only emphasise a
    

    s/emphasise/emphasize/

    (I know, I know, British English is more elegant, but alas.)

NW for point 1.

Anonymous’s picture

Re #33

1. Looks good!

2. This particular line wasn't removed, so it's still in your latest patch.

+++ b/core/modules/update/update.report.inc
@@ -228,7 +228,7 @@ function template_preprocess_update_project_status(&$variables) {
+      $extra_item['data'] = ['#prefix' => '<em>', '#markup' => $value['data'], '#prefix' => '</em>'];
alexpott’s picture

Status: Needs work » Needs review
StatusFileSize
new11.76 KB
new747 bytes

alexpott--

Addressed #34

duaelfr’s picture

drupal_placeholder() was going to be deprecated by #2221771: Mark all simple wrappers in bootstrap.inc and common.inc as deprecated.
As there is a better comment in this patch and as deprecating that function here makes that issue more consistent, I asked to remove that deprectation from the other issue.

wim leers’s picture

Status: Needs review » Reviewed & tested by the community

#36's interdiff is wrong; it only lists #34.2 being fixed, but #34.1 is also fixed :)

stefan.r’s picture

Tests are green, code looks good and grepping for ::placeholder, drupal_placeholder and placeholder shows nothing funny, so RTBC+1, just nits:

+++ b/core/modules/filter/src/FilterFormatListBuilder.php
@@ -94,24 +95,27 @@ public function buildHeader() {
+      // Emphasize the fallback roles text since it is not a role and is
+      // important to understand when configuring filter formats.

wonky grammar here

+++ b/core/includes/bootstrap.inc
@@ -947,10 +948,17 @@ function drupal_static_reset($name = NULL) {
+ *   \Drupal\Component\Utility\SafeMarkup::format() with a %variable in an

"a %variable" also reads odd

+++ b/core/lib/Drupal/Component/Utility/SafeMarkup.php
@@ -232,7 +232,7 @@ public static function format($string, array $args) {
           // Escaped and placeholder.

Is this still true?

core/modules/editor/editor.module
core/modules/filter/src/FilterFormatListBuilder.php
core/modules/filter/src/FilterPermissions.php
core/modules/node/src/Controller/NodeController.php

SafeMarkup class is unused here

+++ b/core/modules/filter/src/FilterFormatListBuilder.php
@@ -94,24 +95,27 @@ public function buildHeader() {
       $roles_markup = $roles ? implode(', ', $roles) : $this->t('No roles may use this format');

Unrelated to this patch, but this implode and others could be candidates for using the CSS-based comma separated item_list in a followup.

+++ b/core/modules/node/src/Controller/NodeController.php
@@ -206,7 +206,11 @@ public function revisionOverview(NodeInterface $node) {
+            '#prefix' => '<em>',
+            '#markup' => $this->t('current revision'),
+            '#suffix' => '</em>',

+++ b/core/modules/update/update.report.inc
@@ -228,7 +228,7 @@ function template_preprocess_update_project_status(&$variables) {
+      $extra_item['data'] = ['#prefix' => '<em>', '#markup' => $value['data'], '#suffix' => '</em>'];

this is on multiple lines in one chunk of code but on 1 line elsewhere, let's do multiple lines everywhere?

alexpott’s picture

Status: Reviewed & tested by the community » Needs work

Doing #39

alexpott’s picture

Status: Needs work » Needs review
StatusFileSize
new3.91 KB
new12.24 KB

Fixed everything that needed fixing.

Is this still true?

Very much so - this patch does not remove placeholder support from SafeMarkup::format or t() at all. And the contents are still escaped. No change here.

stefan.r’s picture

Status: Needs review » Reviewed & tested by the community

Yes i saw that when reading the code, its just that the wording was unclear -- we used to call the placeholder function specifically. It's fine like this anyway.

catch queued 41: 2552579.41.patch for re-testing.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 41: 2552579.41.patch, failed testing.

alexpott’s picture

Status: Needs work » Reviewed & tested by the community
StatusFileSize
new12.11 KB
catch’s picture

Status: Reviewed & tested by the community » Fixed

Committed/pushed to 8.0.x, thanks!

  • catch committed c7d4ab5 on 8.0.x
    Issue #2552579 by alexpott: Remove SafeMarkup::placeholder(), deprecate...
joelpittet’s picture

@alexpott thanks for trying to explain in #28 I guess a picture would have been a bit more useful to me, or to thick to understand.

xjm’s picture

https://www.drupal.org/node/2302363 did not get updated for this change; we need to make sure to update previous change records as well providing new ones.

xjm’s picture

Status: Fixed » Needs work
Issue tags: +Needs change record updates
xjm’s picture

Status: Needs work » Fixed
Issue tags: -Needs change record updates

Sorry, it's fixed now. :)

Status: Fixed » Closed (fixed)

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