|
1 | 1 | # pyright: reportAny=false |
2 | 2 | from __future__ import annotations |
3 | 3 |
|
| 4 | +from typing import final |
| 5 | + |
4 | 6 | from django import template |
5 | 7 | from django.template.base import Parser |
6 | 8 | from django.template.base import Token |
7 | 9 | from django.template.context import Context |
8 | 10 |
|
9 | | -from django_bird._typing import TagBits |
10 | 11 | from django_bird._typing import override |
11 | 12 | from django_bird.components import components |
12 | | -from django_bird.staticfiles import Asset |
13 | 13 | from django_bird.staticfiles import AssetType |
14 | 14 |
|
15 | 15 | CSS_TAG = "bird:css" |
16 | 16 | JS_TAG = "bird:js" |
17 | 17 |
|
18 | 18 |
|
19 | | -def do_asset(parser: Parser, token: Token) -> AssetNode: |
| 19 | +def do_asset(_parser: Parser, token: Token) -> AssetNode: |
20 | 20 | bits = token.split_contents() |
21 | | - asset_type = parse_asset_type(bits) |
22 | | - return AssetNode(asset_type) |
23 | | - |
24 | | - |
25 | | -def parse_asset_type(bits: TagBits) -> AssetType: |
26 | 21 | if len(bits) < 1: |
27 | 22 | msg = "bird:assets tag requires at least one argument" |
28 | 23 | raise template.TemplateSyntaxError(msg) |
29 | | - |
30 | 24 | tag_name = bits[0] |
31 | | - |
32 | | - try: |
33 | | - asset_type = tag_name.split(":")[1] |
34 | | - match asset_type: |
35 | | - case "css": |
36 | | - return AssetType.CSS |
37 | | - case "js": |
38 | | - return AssetType.JS |
39 | | - case _: |
40 | | - raise ValueError(f"Unknown asset type: {asset_type}") |
41 | | - except IndexError as e: |
42 | | - raise ValueError(f"Invalid tag name: {tag_name}") from e |
| 25 | + asset_type = AssetType.from_tag_name(tag_name) |
| 26 | + return AssetNode(asset_type) |
43 | 27 |
|
44 | 28 |
|
| 29 | +@final |
45 | 30 | class AssetNode(template.Node): |
46 | 31 | def __init__(self, asset_type: AssetType): |
47 | 32 | self.asset_type = asset_type |
48 | 33 |
|
49 | 34 | @override |
50 | 35 | def render(self, context: Context) -> str: |
51 | | - component_assets = components.get_assets(self.asset_type) |
52 | | - return self._render_assets(component_assets) |
53 | | - |
54 | | - def _render_assets(self, assets: list[Asset]) -> str: |
| 36 | + assets = components.get_assets(self.asset_type) |
55 | 37 | if not assets: |
56 | 38 | return "" |
57 | | - |
58 | | - if self.asset_type == AssetType.CSS: |
59 | | - tags = ( |
60 | | - f'<link rel="stylesheet" href="{asset.url}">' |
61 | | - for asset in sorted(assets, key=lambda a: a.path) |
62 | | - ) |
63 | | - else: # JS |
64 | | - tags = ( |
65 | | - f'<script src="{asset.url}"></script>' |
66 | | - for asset in sorted(assets, key=lambda a: a.path) |
67 | | - ) |
68 | | - |
69 | | - return "\n".join(tags) |
| 39 | + rendered = {asset.render() for asset in sorted(assets, key=lambda a: a.path)} |
| 40 | + return "\n".join(rendered) |
0 commit comments