Skip to content

Commit 57ee31d

Browse files
Add patchouli:entity stub template (#93)
2 parents 55f704c + 9960f72 commit 57ee31d

File tree

4 files changed

+88
-4
lines changed

4 files changed

+88
-4
lines changed

noxfile.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,12 +271,27 @@ def dummy_setup(session: nox.Session):
271271
"--data=multiloader=false",
272272
)
273273

274+
# Example image:
275+
# PNG image, 16x16, 1-bit indexed color
276+
# Palette: 0 = #202020 1 = #50ff50 (green)
277+
# No compression, filter 0 on all scanlines (none)
278+
image = (
279+
b"\x89PNG\r\n\x1a\n"
280+
b"\0\0\0\x0dIHDR\0\0\0\x10\0\0\0\x10\x01\x03\0\0\0\x25\x3d\x6d\x22"
281+
b"\0\0\0\x06PLTE\x22\x22\x22\x50\xff\x50\xca\xca\x84\x15"
282+
b"\0\0\0\x3bIDAT\x78\x01\x01\x30\0\xcf\xff\0\0\0\0\x7f\xfe\0\x40\x02\0\x40\x02\0\x40\x02\0\x40\x02\0\x40\x02\0\x40\x02\0\x40\x02\0\x40\x02\0\x40\x02\0\x40\x02\0\x40\x02\0\x40\x02\0\x7f\xfe\0\0\0\x92\xd5\x06\x13\xec\x45\xbf\x6a"
283+
b"\0\0\0\0IEND\xae\x42\x60\x82"
284+
)
285+
274286
session.log(f"write_file_tree({DUMMY_PATH}, ...)")
275287
write_file_tree(
276288
DUMMY_PATH,
277289
{
278290
"doc": {
279291
"resources": {
292+
"assets/minecraft/textures/entities": {
293+
"chicken.png": ("wb", image)
294+
},
280295
"assets/dummy/patchouli_books/dummybook": {
281296
"en_us": {
282297
"categories/foo.json": {
@@ -391,6 +406,11 @@ def dummy_setup(session: nox.Session):
391406
],
392407
"text": "have a look at these related entries!!",
393408
},
409+
{
410+
"type": "patchouli:entity",
411+
"entity": "minecraft:chicken",
412+
"text": "ah yes, the chicken. it lays eggs and stuff",
413+
},
394414
{
395415
"type": "patchouli:link",
396416
"url": "https://github.com/hexdoc-dev/hexdoc",
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{% extends "pages/patchouli/page.html.jinja" %}
2+
3+
{% import "macros/formatting.html.jinja" as fmt with context %}
4+
{% import "macros/textures.html.jinja" as texture_macros with context %}
5+
6+
{% block body %}
7+
<h4>
8+
{{- page.name -}}
9+
{%- if page_anchor_id is defined %}
10+
{{- fmt.permalink(page_anchor_id) -}}
11+
{% endif -%}
12+
</h4>
13+
{% block image %}
14+
<p class="image-wrapper">
15+
{{ texture_macros.render_texture(
16+
name=page.entity_name,
17+
texture=page.texture,
18+
class_names=["entity-display"]
19+
) }}
20+
</p>
21+
{% endblock image %}
22+
{{ fmt.styled(page.text) }}
23+
{% endblock %}

src/hexdoc/patchouli/page/pages.py

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@
33

44
from jinja2 import pass_context
55
from jinja2.runtime import Context
6-
from pydantic import Field, ValidationInfo, field_validator, model_validator
6+
from pydantic import (
7+
Field,
8+
PrivateAttr,
9+
ValidationInfo,
10+
field_validator,
11+
model_validator,
12+
)
713

814
from hexdoc.core import Entity, ItemStack, ResourceLocation
915
from hexdoc.minecraft import I18n, LocalizedStr
@@ -47,12 +53,41 @@ class EmptyPage(Page, type="patchouli:empty", template_type="patchouli:page"):
4753

4854

4955
class EntityPage(PageWithText, type="patchouli:entity"):
56+
_entity_name: LocalizedStr = PrivateAttr()
57+
_texture: PNGTexture = PrivateAttr()
58+
5059
entity: Entity
5160
scale: float = 1
5261
offset: float = 0
5362
rotate: bool = True
5463
default_rotation: float = -45
55-
name: LocalizedStr | None = None
64+
name_field: LocalizedStr | None = Field(default=None, serialization_alias="name")
65+
66+
@property
67+
def entity_name(self):
68+
return self._entity_name
69+
70+
@property
71+
def name(self):
72+
if self.name_field is None or not self.name_field.value:
73+
return self._entity_name
74+
return self.name_field
75+
76+
@property
77+
def texture(self):
78+
return self._texture
79+
80+
@model_validator(mode="after")
81+
def _get_texture(self, info: ValidationInfo) -> Self:
82+
# can't be on Entity's validator because it's frozen and
83+
# causes circular references with the PNGTexture
84+
assert info.context is not None
85+
i18n = I18n.of(info)
86+
self._entity_name = i18n.localize_entity(self.entity.id)
87+
self._texture = PNGTexture.load_id(
88+
id="textures/entities" / self.entity.id + ".png", context=info.context
89+
)
90+
return self
5691

5792

5893
class ImagePage(PageWithTitle, type="patchouli:image"):

test/tree.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
else:
99
from typing import Any as JSONValue
1010

11-
FileValue = JSONValue | tuple[Literal["a"], str] | Callable[[str | None], str]
11+
OpenMode = Literal["w", "a", "wb", "ab"]
12+
FileValue = JSONValue | tuple[OpenMode, str | bytes] | Callable[[str | None], str]
1213

1314
FileTree = dict[str, "FileTree | FileValue"]
1415

@@ -28,7 +29,12 @@ def write_file_tree(root: str | Path, tree: FileTree):
2829
case tuple((mode, text)):
2930
# append to existing file
3031
with path.open(mode) as f:
31-
f.write(dedent(text))
32+
if isinstance(text, bytes):
33+
f.write(text)
34+
elif isinstance(text, str):
35+
f.write(dedent(text))
36+
else:
37+
raise TypeError()
3238
case str() as text:
3339
# anything else - usually just text
3440
path.parent.mkdir(parents=True, exist_ok=True)

0 commit comments

Comments
 (0)