django / django/new-features

Support lists of css files on forms.Media

Open
#159 7 comments 7 reactions 0 assignees View on GitHub
Django Core Forms Frontend/JavaScript
Dominant language
No language data
Stars
188
Forks
7
PR merge metrics
No merged PRs in 30d

Description

### Code of Conduct

- [x] I agree to follow Django's Code of Conduct

### Feature Description

Forms.Media could take a list instead of a dict for its css asset list.

### Problem

@codingjoe and @nessita added object-based stylesheet media assets last week. in [#37085](https://code.djangoproject.com/ticket/37085)
This opens up another simlification discussed in the various Form.Media Rejuvenating discussions.
@aaugustin suggesting on the [mailinglist](https://groups.google.com/g/django-developers/c/Hjci3SyDx9k/m/Dd5qTXSTAwAJ) which I came to via the [forum](https://forum.djangoproject.com/t/rejuvenating-vs-deprecating-form-media/21285/15) discussion

It would simlify what is a slightly awkward syntax at present.
The css could change from a dict keyed on media type to a list of "file path strings" or `Stylesheet`'s.
If you need a media=print, use `Stylesheet`

Our default example usage in the docs becomes:
```
from django import forms

class CalendarWidget(forms.TextInput):
class Media:
css = ["pretty.css"]
js = ["animations.js", "actions.js"]
```

And our example of setting media= becomes
```
class Media:
css = [
Stylesheet("pretty.css", media="screen"),
Stylesheet("newspaper.css", media="print"),
]
```
or even
```
class Media:
css = [
"pretty.css",
Stylesheet("newspaper.css", media="print"),
]
```

### Request or proposal

proposal

### Additional Details

The dict approach could be kept for backwards compatiility but no longer documented. Or if could be deprecated as normal.

I've done up a diff for the media docs so you can see the full affect in this [saved diff](https://www.diffchecker.com/ebYQA6tH/)

By default you would not be adding `media="all"` to the tag, it defaults to that anyway.

### Implementation Suggestions

To support dict and list we could normalise everything to lists of MediaAsset/Stylesheet with the correct media set.
```
def __init__(self, media=None, css=None, js=None):
if isinstance(css, list):
self._css_lists = [[
a if isinstance(a, MediaAsset) else Stylesheet(a)
for a in css
]]
elif isinstance(css, dict):
self._css_lists = [[
a if isinstance(a, MediaAsset) else Stylesheet(a, media=medium)
for medium, paths in css.items()
for a in paths
]]
```

The css handling functions can then be simplified.

_css property matches the _js property:
```
@property
def _css(self):
return self.merge(*self._css_lists)
```
This is marked private but something like @dmptrluke's django-csp-helpers package would be affected.

and render simplifies to:
```
def render_css(self, *, attrs=None):
return [path.render(attrs=attrs) for path in self._css]
```

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.