|
9 | 9 | from dataclasses import dataclass |
10 | 10 | from functools import partial |
11 | 11 | from pathlib import Path |
12 | | -from typing import Any, List, NewType, Optional, Set, Tuple, Union, overload |
| 12 | +from typing import Any, Dict, List, NewType, Optional, Set, Tuple, Union, overload |
13 | 13 | from urllib.parse import urlparse |
14 | 14 |
|
15 | 15 | from typing_extensions import Protocol |
@@ -99,10 +99,14 @@ def module_from_template( |
99 | 99 | warning.cIt's best to author a module adhering to the |
100 | 100 | :ref:`Custom Javascript Component` interface instead. |
101 | 101 |
|
| 102 | + **Templates** |
| 103 | +
|
| 104 | + - ``react``: for modules exporting React components |
| 105 | + - ``react-default``: for React modules that use ``export default`` |
| 106 | +
|
102 | 107 | Parameters: |
103 | 108 | template: |
104 | | - The name of the framework template to use with the given ``package`` |
105 | | - (only ``react`` is supported at the moment). |
| 109 | + The name of the framework template to use with the given ``package``. |
106 | 110 | package: |
107 | 111 | The name of a package to load. May include a file extension (defaults to |
108 | 112 | ``.js`` if not given) |
@@ -137,7 +141,7 @@ def module_from_template( |
137 | 141 | if not target_file.exists(): |
138 | 142 | target_file.parent.mkdir(parents=True, exist_ok=True) |
139 | 143 | target_file.write_text( |
140 | | - template_file.read_text().replace("$PACKAGE", package).replace("$CDN", cdn) |
| 144 | + _resolve_template(template_file, {"$PACKAGE": package, "$CDN": cdn}) |
141 | 145 | ) |
142 | 146 |
|
143 | 147 | return WebModule( |
@@ -316,3 +320,24 @@ def _web_module_path(name: str, prefix: str = "") -> Path: |
316 | 320 | directory /= prefix |
317 | 321 | path = directory.joinpath(*name.split("/")) |
318 | 322 | return path.with_suffix(path.suffix) |
| 323 | + |
| 324 | + |
| 325 | +def _resolve_template(file: Path, substitutions: Dict[str, str]) -> str: |
| 326 | + # NOTE: If this needs to be any more complex than it is, we should really |
| 327 | + # reconsider this solution. Either use a real templating solution like Jinja |
| 328 | + # or do something else entirely. |
| 329 | + resolved_lines = [] |
| 330 | + for line in file.read_text().splitlines(): |
| 331 | + if line.startswith("$TEMPLATE:"): |
| 332 | + relative_path = line.split(":", 1)[1].strip() |
| 333 | + inner_template_file = file.parent.joinpath(*relative_path.split("/")) |
| 334 | + resolved_lines.append(_resolve_template(inner_template_file, {})) |
| 335 | + else: |
| 336 | + resolved_lines.append(line) |
| 337 | + |
| 338 | + result = "\n".join(resolved_lines) |
| 339 | + if substitutions: |
| 340 | + for k, v in substitutions.items(): |
| 341 | + result = result.replace(k, v) |
| 342 | + |
| 343 | + return result |
0 commit comments