From b9b6451c880aa386a17a336d1fc30cf07447b4a3 Mon Sep 17 00:00:00 2001 From: Thibaud Colas Date: Tue, 19 Dec 2023 10:45:24 +0000 Subject: [PATCH 1/4] Copy template to new draft DEP doc --- draft/0000-rejuvenate-form-media.rst | 104 +++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 draft/0000-rejuvenate-form-media.rst diff --git a/draft/0000-rejuvenate-form-media.rst b/draft/0000-rejuvenate-form-media.rst new file mode 100644 index 00000000..8e857349 --- /dev/null +++ b/draft/0000-rejuvenate-form-media.rst @@ -0,0 +1,104 @@ +====================== +DEP XXXX: DEP template +====================== + +:DEP: XXXX +:Author: Jacob Kaplan-Moss +:Implementation Team: Jacob Kaplan-Moss +:Shepherd: Andrew Godwin, Carl Meyer +:Status: Draft +:Type: Feature +:Created: 2014-11-16 +:Last-Modified: 2014-11-18 + +.. contents:: Table of Contents + :depth: 3 + :local: + +This DEP provides a sample template for creating your own DEPs. In conjunction +with the content guidelines in `DEP 1 `_, +this should make it easy for you to conform your own DEPs to the format +outlined below. + +Note: if you are reading this DEP via the web, you should first grab `the source +of this DEP `_ in +order to complete the steps below. **DO NOT USE THE HTML FILE AS YOUR +TEMPLATE!** + +To get the source this (or any) DEP, look at the top of the Github page +and click "raw". + +If you're unfamiliar with reStructuredText (the format required of DEPs), +see these resources: + +* `A ReStructuredText Primer`__, a gentle introduction. +* `Quick reStructuredText`__, a users' quick reference. +* `reStructuredText Markup Specification`__, the final authority. + +__ http://docutils.sourceforge.net/docs/rst/quickstart.html +__ http://docutils.sourceforge.net/docs/rst/quickref.html +__ http://docutils.sourceforge.net/spec/rst/reStructuredText.html + +Once you've made a copy of this template, remove this abstract, fill out the +metadata above and the sections below, then submit the DEP. Follow the +guidelines in `DEP 1 `_. + +Abstract +======== + +This should be a short (~200 word) description of the technical issue being +addressed. + +This (and the above metadata) is the only section strictly required to submit a +draft DEP; the following sections can be barebones and fleshed out as you work +through the DEP process. + +Specification +============= + +This section should contain a complete, detailed technical specification should +describe the syntax and semantics of any new feature. The specification should +be detailed enough to allow implementation -- that is, developers other than the +author should (given the right experience) be able to independently implement +the feature, given only the DEP. + +Motivation +========== + +This section should explain *why* this DEP is needed. The motivation is critical +for DEPs that want to add substantial new features or materially refactor +existing ones. It should clearly explain why the existing solutions are +inadequate to address the problem that the DEP solves. DEP submissions without +sufficient motivation may be rejected outright. + +Rationale +========= + +This section should flesh out out the specification by describing what motivated +the specific design and why particular design decisions were made. It +should describe alternate designs that were considered and related work. + +The rationale should provide evidence of consensus within the community and +discuss important objections or concerns raised during discussion. + +Backwards Compatibility +======================= + +If this DEP introduces backwards incompatibilities, you must must include this +section. It should describe these incompatibilities and their severity, and what +mitigation you plan to take to deal with these incompatibilities. + +Reference Implementation +======================== + +If there's an implementation of the feature under discussion in this DEP, +this section should include or link to that implementation and provide any +notes about installing/using/trying out the implementation. + +Copyright +========= + +This document has been placed in the public domain per the Creative Commons +CC0 1.0 Universal license (http://creativecommons.org/publicdomain/zero/1.0/deed). + +(All DEPs must include this exact copyright statement.) From 07962bd67947104c038514124b158d8621d1bdf6 Mon Sep 17 00:00:00 2001 From: Thibaud Colas Date: Tue, 19 Dec 2023 10:58:32 +0000 Subject: [PATCH 2/4] Add first draft content --- draft/0000-rejuvenate-form-media.rst | 107 ++++++++++++--------------- 1 file changed, 49 insertions(+), 58 deletions(-) diff --git a/draft/0000-rejuvenate-form-media.rst b/draft/0000-rejuvenate-form-media.rst index 8e857349..87a7667b 100644 --- a/draft/0000-rejuvenate-form-media.rst +++ b/draft/0000-rejuvenate-form-media.rst @@ -1,75 +1,52 @@ ====================== -DEP XXXX: DEP template +DEP XXXX: Rejuvenate form media ====================== :DEP: XXXX -:Author: Jacob Kaplan-Moss -:Implementation Team: Jacob Kaplan-Moss -:Shepherd: Andrew Godwin, Carl Meyer +:Author: Thibaud Colas +:Implementation Team: You? People in the `forum thread: Rejuvenating vs deprecating Form.Media `_ +:Shepherd: You? :Status: Draft :Type: Feature -:Created: 2014-11-16 -:Last-Modified: 2014-11-18 +:Created: 2023-12-12 +:Last-Modified: 2023-12-19 .. contents:: Table of Contents :depth: 3 :local: -This DEP provides a sample template for creating your own DEPs. In conjunction -with the content guidelines in `DEP 1 `_, -this should make it easy for you to conform your own DEPs to the format -outlined below. - -Note: if you are reading this DEP via the web, you should first grab `the source -of this DEP `_ in -order to complete the steps below. **DO NOT USE THE HTML FILE AS YOUR -TEMPLATE!** - -To get the source this (or any) DEP, look at the top of the Github page -and click "raw". - -If you're unfamiliar with reStructuredText (the format required of DEPs), -see these resources: - -* `A ReStructuredText Primer`__, a gentle introduction. -* `Quick reStructuredText`__, a users' quick reference. -* `reStructuredText Markup Specification`__, the final authority. - -__ http://docutils.sourceforge.net/docs/rst/quickstart.html -__ http://docutils.sourceforge.net/docs/rst/quickref.html -__ http://docutils.sourceforge.net/spec/rst/reStructuredText.html - -Once you've made a copy of this template, remove this abstract, fill out the -metadata above and the sections below, then submit the DEP. Follow the -guidelines in `DEP 1 `_. - Abstract ======== -This should be a short (~200 word) description of the technical issue being -addressed. - -This (and the above metadata) is the only section strictly required to submit a -draft DEP; the following sections can be barebones and fleshed out as you work -through the DEP process. +See `forum thread: Rejuvenating vs deprecating Form.Media `_. +We want `form.Media `_ to catch up with modern web standards, so Django projects can more easily leverage those standards. Specification ============= -This section should contain a complete, detailed technical specification should -describe the syntax and semantics of any new feature. The specification should -be detailed enough to allow implementation -- that is, developers other than the -author should (given the right experience) be able to independently implement -the feature, given only the DEP. +See the `MDN script element documentation `_ and `link element documentation `_. + +Here are requirements which Django could/should better support: + +- ES modules +- Import maps +- Dynamic module imports +- async, defer scripts +- CSPs via nonce attributes +- integrity attribute +- fetchpriority attribute +- nomodule attribute +- Arbitrary script attributes +- Preloading / speculative loading +- Resource ordering (see `capo.js `_) +- Web Components + Motivation ========== -This section should explain *why* this DEP is needed. The motivation is critical -for DEPs that want to add substantial new features or materially refactor -existing ones. It should clearly explain why the existing solutions are -inadequate to address the problem that the DEP solves. DEP submissions without -sufficient motivation may be rejected outright. +`form.Media `_ is a good API to manage a form widget’s dependencies. +Though not all projects need to keep a strict record of each widget’s dependencies Rationale ========= @@ -84,21 +61,35 @@ discuss important objections or concerns raised during discussion. Backwards Compatibility ======================= -If this DEP introduces backwards incompatibilities, you must must include this -section. It should describe these incompatibilities and their severity, and what -mitigation you plan to take to deal with these incompatibilities. +At this stage I wouldn’t expect this to introduce any backwards-incompatible changes. If we did so, it would be with a very gradual deprecation path, likely only in the interest of: + +- Better performance (for example default to more modern script loading techniques) +- Better security (for example default to… more modern script loading techniques) Reference Implementation ======================== -If there's an implementation of the feature under discussion in this DEP, -this section should include or link to that implementation and provide any -notes about installing/using/trying out the implementation. +Here are the most fully-fledged implementations so far: + +- https://github.com/matthiask/django-js-asset/ +- https://github.com/rails/importmap-rails + +Other references: + +- https://github.com/dropseed/django-importmap +- https://github.com/tonysm/importmap-laravel + +TODOs +===== + +- Add more possible requirements +- Review https://github.com/wsvincent/awesome-django for packages with form media-related functionality. +- Review https://djangopackages.org/ for packages with form media-related functionality. +- Update https://github.com/st3v3nmw/awesome-django-performance with existing performance-related Django packages relating to form assets. +- Also update https://github.com/wsvincent/awesome-django with good packages in this category Copyright ========= This document has been placed in the public domain per the Creative Commons CC0 1.0 Universal license (http://creativecommons.org/publicdomain/zero/1.0/deed). - -(All DEPs must include this exact copyright statement.) From a968cbddcd8d733f5d1c58c3afb772206d26a804 Mon Sep 17 00:00:00 2001 From: Matthias Kestenholz Date: Fri, 14 Feb 2025 17:34:15 +0100 Subject: [PATCH 3/4] Continue working on the DEP --- draft/0000-rejuvenate-form-media.rst | 142 ++++++++++++++++++++++----- 1 file changed, 120 insertions(+), 22 deletions(-) diff --git a/draft/0000-rejuvenate-form-media.rst b/draft/0000-rejuvenate-form-media.rst index 87a7667b..9b44553f 100644 --- a/draft/0000-rejuvenate-form-media.rst +++ b/draft/0000-rejuvenate-form-media.rst @@ -3,13 +3,13 @@ DEP XXXX: Rejuvenate form media ====================== :DEP: XXXX -:Author: Thibaud Colas +: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: 2023-12-19 +:Last-Modified: 2025-02-14 .. contents:: Table of Contents :depth: 3 @@ -18,35 +18,126 @@ DEP XXXX: Rejuvenate form media Abstract ======== -See `forum thread: Rejuvenating vs deprecating Form.Media `_. -We want `form.Media `_ to catch up with modern web standards, so Django projects can more easily leverage those standards. +``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 ============= -See the `MDN script element documentation `_ and `link element documentation `_. +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") + # Alter the signature to allow src to be passed as a keyword argument. + 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 ``