diff --git a/draft/0000-rejuvenate-form-media.rst b/draft/0000-rejuvenate-form-media.rst new file mode 100644 index 0000000..5762917 --- /dev/null +++ b/draft/0000-rejuvenate-form-media.rst @@ -0,0 +1,192 @@ +====================== +DEP XXXX: Rejuvenate form media +====================== + +:DEP: XXXX +:Author: Matthias Kestenholz, Thibaud Colas +:Implementation Team: You? People in the `forum thread: Rejuvenating vs deprecating Form.Media `_ +:Shepherd: You? +:Status: Draft +:Type: Feature +:Created: 2023-12-12 +:Last-Modified: 2025-02-14 + +.. contents:: Table of Contents + :depth: 3 + :local: + +Abstract +======== + +``forms.Media`` allows Django's forms, widgets and the administration interface to define required CSS and JavaScript assets, collecting the required assets from all widgets on a page, ordering them and outputting the result to the browser. + +The functionality has been somewhat neglected since it has been introduced initially, and the question was raised whether `the media object should be rejuvenated or deprecated `_. The consensus was that ``forms.Media`` was widely used and seen as useful. + +In the meantime, `object-based Script objects `_ were introduced to Django adding an easy way to add attributes to script tags. This DEP proposes ways to further enhance ``forms.Media`` so Django projects can more easily leverage the Web standards around asset loading. + + +Specification +============= + +A renewed ``forms.Media`` should take full advantage of the object-based assets functionality. + +The ``Script`` implementation is already there. + +A new ``Stylesheet`` implementation can be easily added by reusing the existing ``django.forms.widgets.MediaAsset`` class, while preserving the ``media="all"`` default of the existing code: + +.. code-block:: python + + class Stylesheet(MediaAsset): + element_template = '' + + def __init__(self, path, **attributes): + attributes.setdefault("media", "all") + super().__init__(path, **attributes) + + +The current differentiation between CSS and JS assets isn't necessary, instead, assets can be immediately converted into object-based assets and collected in one list. The existing ``_css_lists`` and ``_js_lists`` attributes of ``forms.Media`` are replaced by a single ``_assets_lists`` attribute. This avoids the confusion of allowing to specify the medium for stylesheets both in the dictionary key (``css = {"all": ["style.css"]}``) and also in the object (``Stylesheet("style.css", media="all")``). + +Browser support for `importmaps `_ has reached baseline in 2023. However, browsers still only support one importmap per page, which means that there has to exist a way to aggregate importmap entries from all sorts of forms, widgets, etc. The ``forms.Media`` class already does something like this, so it could be easily extended to also allow importmap entries: + +.. code-block:: python + + @html_safe + @dataclass(eq=True) + class ImportMapImport: + key: str + value: str + scope: str | None = None + + def __hash__(self): + return hash((self.key, self.value, self.scope)) + + def __str__(self): + return "" + +The ``forms.Media`` rendering should then be extended to automatically collect importmap entries and produce the appropriate ``