mdn / yari

The platform code behind MDN Web Docs
Mozilla Public License 2.0
1.18k stars 502 forks source link

Deprecated_Header Macro: Add mechanism to specify reason/replacement #8969

Open hamishwillee opened 1 year ago

hamishwillee commented 1 year ago

Summary

The {{Deprecated_Header}} macro explains that a feature is deprecated. Often there is a replacement that we'd like people to use instead. To indicate this we usually need to add a second note with information about why we're deprecating and the replacement API. It ends up being repetitive and inefficient use of space.

Proposal is to allow users freetext to indicate the reason/replacement if they so wish.

For example, in https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Digest I might have:

{{Deprecated_Header("This header was removed from the specification in [draft 8](https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-digest-headers-08). Use {{HTTPHeader("Repr-Digest")}} instead. Forid-*digest algorithms, use {{HTTPHeader("Content-Digest")}}")}}

URL

This header was removed from the specification in [draft 8](https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-digest-headers-08). Use {{HTTPHeader("Repr-Digest")}} instead. For id-* digest algorithms, use {{HTTPHeader("Content-Digest")}}

Reproduction steps

1. 2. 3.

Expected behavior

One box to cover all deprecation information.

Actual behavior

Two boxes and duplication of information.

Device

Other (specify below)

Browser

Other (specify below)

Browser version

Stable

Operating system

Other (specify below)

Screenshot

No response

Anything else?

No response

Validations

jfrech commented 1 year ago

Your example calls a macro with depth two, so -- if this feature is present -- one should probably escape the second:

{{Deprecated_Header("... Use {{HTTPHeader(\"Repr-Digest\")}} instead. For `id-*` ...
jfrech commented 1 year ago

Maybe DeprecatedHTTPHeader as a macro name would be a better fit than Deprecated_Header. To closer resemble the already present HTTPHeader.

hamishwillee commented 1 year ago

Maybe DeprecatedHTTPHeader as a macro name would be a better fit than Deprecated_Header. To closer resemble the already present HTTPHeader.

We're trying to have as few macros as possible. Unless there is some reason that HTTP deprecation is special in some way, we should just have the Deprecated_Header.

Your example calls a macro with depth two, so -

I don't know what you mean

jfrech commented 1 year ago

Then I retract my comment regarding the name.

What I mean is that I am sceptical if {{Deprecated_Header("Use {{HTTPHeader("Another-Header")}}.")}} or {{Deprecated_Header("Use {{HTTPHeader(\"Another-Header\")}}.")}} is syntactically feasible for the macro engine since inside the macro Deprecated_Header's argument another macro is present.

hamishwillee commented 1 year ago

Ah, you might be right. That's a challenge for the site developers to work out :-)

Josh-Cena commented 1 year ago

I don't think it's nice to expect anything more complex than simple text fragments in macro arguments. Remember that macros are replaced after Markdown rendering is done, which means you don't get to use any of the Markdown syntaxes and can only use HTML markup. I don't think you can nest macros either, and it would be tricky to make that work. A better way would be to migrate to metadata-based header injection, and then find another way to annotate the deprecation reason—for example, another metadata field:

---
status: deprecated
deprecation_reason: Use {{HTTPHeader("Another-Header")}}.
---

And then we can render the header as soon as possible, before Markdown parsing is done. Another possible way is to say "the first note box before any kind of prose becomes the deprecation note":

---
status: deprecated
---

> **Note:** Use {{HTTPHeader("Another-Header")}}.

<!-- After compilation -->

<div class="notecard deprecated" id="sect1">
  <p><strong>Deprecated:</strong> This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes. Avoid using it, and update existing code if possible; see the <a href="#browser_compatibility">compatibility table</a> at the bottom of this page to guide your decision. Be aware that this feature may cease to work at any time.</p>
  <p>Use {{HTTPHeader("Another-Header")}}.</p>
</div>
hamishwillee commented 1 year ago

Yes, automated from metadata is my preference for all these header macros. In particular, even if compatibility came from BCD we could still use content front matter for the reason.

hamishwillee commented 1 year ago

@wbamberg We know we want metadata generation of this kind of data (IMO) so let's plan for that. Would you want whitespace, or something more fine-grained. As I try it - see below - I think a reason string makes more sense.

---
status: 
  - non-standard #added just for interest
  - deprecated
    - alternative: '{{HTTPHeader("Another-Header")}}.'
    - alternative: 'For id-* digest algorithms, use {{HTTPHeader("Content-Digest")}}")}}'
    - reason: Removed from the specification in [draft 8](https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-digest-headers-08).
---
Josh-Cena commented 1 year ago

@hamishwillee Unfortunately that's not valid YAML—the status array is already a list of strings; you can't have properties on a string.

hamishwillee commented 1 year ago

Fair enough - it is the "data to include" that I hope to explore. The actual format will, as you say, need to be valid.

jfrech commented 1 year ago

How about

status:
  - deprecated
  - deprecated.transition See {{HTTPHeader("A")}}. In this slightly less common case, see {{HTTPHeader("B")}}

? But I do also entertain the thought that a simple **Note:** may already be sufficient.

hamishwillee commented 1 year ago

That might work. The problem with a note is that you end up with two boxes, when one would do. Also, if there is a place for a reason, people are more likely to remember they need to do one.

caugner commented 11 months ago

Unfortunately, I don't think we want to support macro usage within metadata or macro parameters.

Would it be a viable alternative to explain "what to use instead" in the "Browser compatibility" section that the deprecated header already links to? Or have a separate section (e.g. "Deprecated feature") for this that is mandatory for deprecated features and explains when and why the feature has been deprecated and what to use instead?

hamishwillee commented 11 months ago

Unfortunately, I don't think we want to support macro usage within metadata or macro parameters.

The whole thing with macros in macros is a red-herring. There is no need to ever use a macro in a macro - we can just add an explicit link.

Would it be a viable alternative to explain "what to use instead" in the "Browser compatibility" section that the deprecated header already links to? Or have a separate section (e.g. "Deprecated feature") for this that is mandatory for deprecated features and explains when and why the feature has been deprecated and what to use instead?

I don't think so. Firstly, way we have our compat now means that you could at some point auto inject the compat and spec stuff without this boilerplate. If you add stuff to the compat then that becomes impossible. Secondly, the reason for deprecation isn't always known so we can't have a mandatory section.

I'd prefer optional text in the macro (or in the metadata if we can auto inject deprecation headings from metadata) because it is the simplest and most obvious way to do it.

wbamberg commented 11 months ago

It might be helpful to have a look at a few (or a lot of) cases of what we actually want to have as "deprecation details". I think a concern is that it will sometimes/often be quite nuanced and involve quite a lot of prose, and I don't think metadata is the right place for that. Which makes me think this:

Or have a separate section (e.g. "Deprecated feature") for this that is mandatory for deprecated features and explains when and why the feature has been deprecated and what to use instead?

...is likely to be a better option.

Secondly, the reason for deprecation isn't always known so we can't have a mandatory section.

For that matter, if you auto-generate deprecation headings from a metadata item, you can look in the page to see if a heading exists like deprecation_details or whatever, and link to it if it exists, and not if it doesn't.

hamishwillee commented 11 months ago

FWIW ^^^ @wbamberg

OK, so I looked through about 100 cases in web APIs. Estimate about 30% had deprecation information. Nothing was nuanced.

  1. Where detailed information was provided it was not in a note box but just part of the description - see https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/border

  2. Most common case was stuff like this:

    Note: The correct way of creating a {{domxref("CompositionEvent")}} is to use the constructor {{domxref("CompositionEvent.CompositionEvent", "CompositionEvent()")}}.

  3. Some larger cases - this could be reduced significantly:

    Note: This method was part of an attempt to create a typed CSS Object Model. This attempt has been abandoned, and most browsers do not implement it.

    To achieve your purpose, you can use:

  4. Lots more examples here

Note: This method was part of an attempt to create a typed CSS Object Model. This attempt has been abandoned, and most browsers do not implement it.

Note: This is a legacy method which has been replaced by the standard method {{domxref("CSSStyleSheet.deleteRule", "deleteRule()")}}. You should use that instead.

Note: Do not use this method anymore, as it is deprecated.

Rather than using the feature, instead use specific event constructors, like {{domxref("CustomEvent.CustomEvent", "CustomEvent()")}}. The page on Creating and triggering events gives more information about the way to use those.

2

Warning: This interface is deprecated and is no more on the standard track. Do not use it anymore. Use the File and Directory Entries API instead.

Note: Support for the {{htmlelement("applet")}} element has been removed by all browsers. Therefore, calling document.applets always returns an empty collection.

Note: Use the {{domxref("TouchEvent.TouchEvent", "TouchEvent()")}} constructor.

Note: Since this property is deprecated, you can determine if fullscreen mode is active on the document by checking to see if {{DOMxRef("Document.fullscreenElement")}} is not null.

Note: As this method is deprecated, use the three {{domxref("AudioListener.positionX", "positionX")}}, {{domxref("AudioListener.positionY", "positionY")}}, and {{domxref("AudioListener.positionZ", "positionZ")}} properties instead.

Warning: This feature has been deprecated and should be replaced by an AudioWorklet.

Note: This feature was replaced by AudioWorklets and the {{domxref("AudioWorkletNode")}} interface.

My take on this is that most of the time you just have that "this was replaced by X" note. If there is more detail to add, then you could easily add text "Deprecation information can be found in [LINK HEADING]".

Obviously you could do a lot more but this is simple. I don't see the justification for more.

caugner commented 11 months ago

Related: https://github.com/mdn/mdn/issues/388 suggests to add "Deprecation details, with focus on date & reason of deprecation".

hamishwillee commented 6 months ago

@Rumyra When you're thinking about header banners, this would be a good thing to consider. Right now we don't specify a reason for deprecation, or an alternative. The alternative in particular would be useful, if known.

Rumyra commented 5 months ago

Thanks @hamishwillee - I have capture this in the research doc already (which I will share with you directly)