Skip to content

Commit

Permalink
Merge pull request #11 from thismatters/multi-css
Browse files Browse the repository at this point in the history
Multi css
  • Loading branch information
thismatters authored Feb 29, 2024
2 parents 379d058 + 435481c commit a211d45
Show file tree
Hide file tree
Showing 9 changed files with 121 additions and 61 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
- name: Build a binary wheel and a source tarball
run: python3 -m build
- name: Store the distribution packages
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: python-package-distributions
path: dist/
Expand All @@ -46,7 +46,7 @@ jobs:

steps:
- name: Download all the dists
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: python-package-distributions
path: dist/
Expand All @@ -67,7 +67,7 @@ jobs:

steps:
- name: Download all the dists
uses: actions/download-artifact@v3
uses: actions/download-artifact@v4
with:
name: python-package-distributions
path: dist/
Expand Down Expand Up @@ -111,7 +111,7 @@ jobs:

# steps:
# - name: Download all the dists
# uses: actions/download-artifact@v3
# uses: actions/download-artifact@v4
# with:
# name: python-package-distributions
# path: dist/
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## Version 0.2.1
### Added
* Recursive lookup of CSS bundles in vite manifest.
* Support for displaying several CSS files per component.


## Version 0.2.0
### Added
* This changelog!
Expand Down
3 changes: 3 additions & 0 deletions demo_project/django_svelte_demo/static/Plain.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
class Something {

}
1 change: 0 additions & 1 deletion django_svelte/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,4 @@ def configure(self):
raise ImproperlyConfigured(f"Vite manifest must exist at path! {_path}")
with open(_path) as manifest:
self.configured_data["_VITE_MANIFEST"] = json.load(manifest)
print(self.configured_data["_VITE_MANIFEST"])
return self.configured_data
4 changes: 2 additions & 2 deletions django_svelte/templates/django_svelte/display_svelte_css.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{% if css_bundle_url %}
{% for css_bundle_url in css_bundle_urls %}
<link href="{{ css_bundle_url }}" rel="stylesheet">
{% endif %}
{% endfor %}
68 changes: 45 additions & 23 deletions django_svelte/templatetags/django_svelte.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,35 +6,61 @@
register = template.Library()


def get_hashed_filename(*, component_name, file_type):
def clean_hashed_filename(filename):
# strip the vite `build.assetsDir` from the filename
if filename.startswith(settings.DJANGO_SVELTE_VITE_ASSETSDIR):
_len = len(settings.DJANGO_SVELTE_VITE_ASSETSDIR)
filename = filename[_len:]
return filename


def get_bundle_hashed_filename(*, component_name):
key = f"{settings.DJANGO_SVELTE_ENTRYPOINT_PREFIX}{component_name}.js"
entry = settings.DJANGO_SVELTE__VITE_MANIFEST.get(key)
if entry is None:
return None
if not entry.get("isEntry", False):
return None
if file_type == "js":
filename = entry["file"]
if file_type == "css":
_css = entry.get("css", [])
if not _css:
return None
filename = _css[0]
# strip the vite build.assetsDir from the filename
if filename.startswith(settings.DJANGO_SVELTE_VITE_ASSETSDIR):
_len = len(settings.DJANGO_SVELTE_VITE_ASSETSDIR)
filename = filename[_len:]
filename = entry["file"]
filename = clean_hashed_filename(filename)
return filename


def get_static_file_url(*, component_name, file_type="js"):
def _get_css_bundle_hashed_filenames(*, key):
entry = settings.DJANGO_SVELTE__VITE_MANIFEST.get(key)
bundles = entry.get("css", [])
for subkey in entry.get("imports", []):
bundles.extend(_get_css_bundle_hashed_filenames(key=subkey))
return bundles


def get_css_bundle_hashed_filenames(*, component_name):
key = f"{settings.DJANGO_SVELTE_ENTRYPOINT_PREFIX}{component_name}.js"
bundles = _get_css_bundle_hashed_filenames(key=key)
return [clean_hashed_filename(b) for b in set(bundles)]


def get_css_bundle_urls(*, component_name):
filenames = []
if settings.DJANGO_SVELTE__VITE_MANIFEST is not None:
filenames = get_css_bundle_hashed_filenames(component_name=component_name)
else:
filenames.append(f"{component_name}.css")
cleaned_bundles = []
for filename in filenames:
found_file = finders.find(filename)
if found_file is None:
continue
cleaned_bundles.append(staticfiles_storage.url(filename))
return cleaned_bundles


def get_bundle_url(*, component_name):
filename = None
if settings.DJANGO_SVELTE__VITE_MANIFEST is not None:
filename = get_hashed_filename(
component_name=component_name, file_type=file_type
)
filename = get_bundle_hashed_filename(component_name=component_name)
else:
filename = f"{component_name}.{file_type}"
filename = f"{component_name}.js"
if filename is None:
return None
static_file = finders.find(filename)
Expand All @@ -55,9 +81,7 @@ def display_svelte_css(component_name):
component_name = de_svelte(component_name)

return {
"css_bundle_url": get_static_file_url(
component_name=component_name, file_type="css"
),
"css_bundle_urls": get_css_bundle_urls(component_name=component_name),
}


Expand All @@ -67,9 +91,7 @@ def display_svelte(component_name, component_props=None):
component_props = component_props or {}

return {
"bundle_url": get_static_file_url(
component_name=component_name, file_type="js"
),
"bundle_url": get_bundle_url(component_name=component_name),
"element_id": f"{component_name.lower()}-target",
"props_name": f"{component_name.lower()}-props",
"props": component_props,
Expand Down
5 changes: 4 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
name="django-svelte",
author="Paul Stiverson",
url="https://github.com/thismatters/django-svelte/",
version="0.2.0",
version="0.2.1",
packages=find_packages(exclude=("tests", "demo_project")),
license="MIT",
description="Facilitates adding Svelte frontend to Django",
Expand All @@ -25,11 +25,14 @@
"Intended Audience :: Developers",
"Natural Language :: English",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Framework :: Django",
"Framework :: Django :: 3.2",
"Framework :: Django :: 4.1",
"Framework :: Django :: 4.2",
Expand Down
87 changes: 57 additions & 30 deletions tests/test_django_svelte.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
from django.test import override_settings

from django_svelte.templatetags.django_svelte import (
get_hashed_filename,
get_static_file_url,
clean_hashed_filename,
get_bundle_hashed_filename,
_get_css_bundle_hashed_filenames,
get_css_bundle_hashed_filenames,
get_css_bundle_urls,
get_bundle_url,
de_svelte,
display_svelte_css,
display_svelte,
Expand All @@ -11,42 +15,34 @@

class TestGetStaticFileUrl:
def test_none(self):
assert (
get_static_file_url(component_name="not-a_file", file_type="asdf") is None
)
assert get_bundle_url(component_name="not-a_file") is None

def test_real(self):
assert (
get_static_file_url(component_name="real_file", file_type="txt")
== "/static/real_file.txt"
)
assert get_bundle_url(component_name="real_file") == "/static/real_file.js"

@override_settings(
DJANGO_SVELTE__VITE_MANIFEST={
"src/Hashed.js": {"isEntry": True, "file": "assets/Hashed-asdfsafd.js"}
}
)
def test_hashed(self):
assert (
get_static_file_url(component_name="Hashed", file_type="js")
== "/static/Hashed-asdfsafd.js"
)
assert get_bundle_url(component_name="Hashed") == "/static/Hashed-asdfsafd.js"

@override_settings(
DJANGO_SVELTE__VITE_MANIFEST={
"src/Bashed.js": {"isEntry": True, "file": "assets/Bashed-asdfsafd.js"}
}
)
def test_hashed_missing(self):
assert get_static_file_url(component_name="Bashed", file_type="js") is None
assert get_bundle_url(component_name="Bashed") is None

@override_settings(
DJANGO_SVELTE__VITE_MANIFEST={
"src/Bashed.js": {"isEntry": True, "file": "assets/Bashed-asdfsafd.js"}
}
)
def test_hashed_absent(self):
assert get_static_file_url(component_name="Hashed", file_type="js") is None
assert get_bundle_url(component_name="Hashed") is None


def test_de_svelte():
Expand All @@ -59,10 +55,14 @@ def test_de_svelte_no_change():

def test_display_svelte_css():
assert display_svelte_css("Something.svelte") == {
"css_bundle_url": "/static/Something.css"
"css_bundle_urls": ["/static/Something.css"]
}


def test_display_svelte_css_missing():
assert display_svelte_css("Plain.svelte") == {"css_bundle_urls": []}


def test_display_svelte():
assert display_svelte("Something.svelte", component_props={"great": "stuff"}) == {
"bundle_url": "/static/Something.js",
Expand All @@ -79,39 +79,66 @@ class TestGetHashedFilename:
}
)
def test_good(self):
assert (
get_hashed_filename(component_name="App", file_type="js")
== "App-asdfsafd.js"
)
assert get_bundle_hashed_filename(component_name="App") == "App-asdfsafd.js"

@override_settings(
DJANGO_SVELTE__VITE_MANIFEST={
"src/App.js": {"isEntry": True, "css": ["assets/App-asdfsafd.css"]}
"a.js": {"imports": ["b.js", "c.js"], "css": ["assets/a.css"]},
"src/App.js": {
"isEntry": True,
"css": ["assets/App-asdfsafd.css"],
"imports": ["a.js", "b.js"],
},
"b.js": {"imports": ["c.js"], "css": ["assets/b.css"]},
"c.js": {},
}
)
def test_css(self):
assert (
get_hashed_filename(component_name="App", file_type="css")
== "App-asdfsafd.css"
)
css = _get_css_bundle_hashed_filenames(key="src/App.js")
print(css)
assert "assets/App-asdfsafd.css" in css
assert "assets/a.css" in css
assert "assets/b.css" in css
# this list is not deduped!
assert len(css) == 4

@override_settings(
DJANGO_SVELTE__VITE_MANIFEST={
"a.js": {"imports": ["b.js", "c.js"], "css": ["assets/a.css"]},
"src/App.js": {
"isEntry": True,
"css": ["assets/App-asdfsafd.css"],
"imports": ["a.js", "b.js"],
},
"b.js": {"imports": ["c.js"], "css": ["assets/b.css"]},
"c.js": {},
}
)
def test_get_css_bundle_hashed_filenames(self):
css = get_css_bundle_hashed_filenames(component_name="App")
print(css)
assert "App-asdfsafd.css" in css
assert "a.css" in css
assert "b.css" in css
assert len(css) == 3

@override_settings(DJANGO_SVELTE__VITE_MANIFEST={"src/App.js": {"isEntry": True}})
def test_css_none(self):
assert get_hashed_filename(component_name="App", file_type="css") is None
assert get_css_bundle_urls(component_name="App") == []

@override_settings(
DJANGO_SVELTE__VITE_MANIFEST={
"src/App.js": {"isEntry": True, "file": "assets/App-asdfsafd.js"}
}
)
def test_nonexistent(self):
assert get_hashed_filename(component_name="Abb", file_type="js") is None
assert get_bundle_hashed_filename(component_name="Abb") is None

@override_settings(
DJANGO_SVELTE__VITE_MANIFEST={"src/App.js": {"file": "assets/App-asdfsafd.js"}}
)
def test_nonentry(self):
assert get_hashed_filename(component_name="App", file_type="js") is None
assert get_bundle_hashed_filename(component_name="App") is None

@override_settings(
DJANGO_SVELTE__VITE_MANIFEST={
Expand All @@ -120,7 +147,7 @@ def test_nonentry(self):
DJANGO_SVELTE_VITE_ASSETSDIR="bassets/",
)
def test_different_assetsdir(self):
assert get_hashed_filename(component_name="App", file_type="js") is None
assert get_bundle_hashed_filename(component_name="App") is None

@override_settings(
DJANGO_SVELTE__VITE_MANIFEST={
Expand All @@ -129,4 +156,4 @@ def test_different_assetsdir(self):
DJANGO_SVELTE_ENTRYPOINT_PREFIX="src/entrypoints/",
)
def test_different_prefix(self):
assert get_hashed_filename(component_name="App", file_type="js") is None
assert get_bundle_hashed_filename(component_name="App") is None

0 comments on commit a211d45

Please sign in to comment.