Un exemplaire d'élément de jeu posé sur un écran reste maintenant lié à son modèle

Jusqu'ici, poser un élément de jeu depuis le catalogue ("Mes éléments de
jeu") copiait tout son arbre en base (instantiate_template_tree) : chaque
exemplaire devenait indépendant, y compris de son propre modèle - modifier
l'élément de jeu dans son éditeur n'avait plus aucun effet sur les
exemplaires déjà posés ailleurs.

Change ce comportement pour qu'un exemplaire reste TOUJOURS lié à son
modèle, sur le même principe déjà utilisé par un modèle de ligne de
Répéteur (jamais copié, rechargé en direct à chaque affichage - voir
_load_template_tree/_render_repeater) : add_element.py ne crée plus
qu'UNE SEULE ligne plate (avec sa position/taille propres à cet
exemplaire) au lieu de copier tout l'arbre, et render_element_html.py
recharge le contenu depuis l'écran-modèle à chaque rendu quand
element_type_id est réglé. Modifier l'élément de jeu dans son propre
éditeur met donc à jour tous ses exemplaires déjà posés, sur n'importe
quel écran (y compris ceux placés AVANT ce correctif, qui portaient déjà
element_type_id sur leur ligne de premier niveau), sans avoir à les
retoucher un par un.

Contrepartie assumée (discutée avec l'utilisateur avant ce changement) :
un exemplaire ne peut plus être personnalisé individuellement à
l'INTÉRIEUR (texte, couleur d'un enfant précis...) - seules sa position et
sa taille sur l'écran restent propres à chaque exemplaire. Pour changer le
contenu, il faut désormais passer par l'éditeur de l'élément de jeu
lui-même.

instantiate_template_tree.py, devenu inutilisé, est supprimé.

Ajoute tests/test_element_type_live_instances.py (mise à jour d'un
exemplaire déjà posé, propagation jusqu'à "Jouer", position toujours
indépendante par exemplaire) et met à jour un commentaire de test devenu
obsolète dans test_screens_and_elements.py.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
william
2026-08-25 15:26:45 +02:00
co-authored by Claude Sonnet 5
parent 79fe04c6ac
commit e9a991ed13
6 changed files with 124 additions and 73 deletions
+26 -1
View File
@@ -17,6 +17,7 @@ from .render_onglets import _render_onglets
from .render_icone import _render_icone
from .resolve_bound_row import _resolve_bound_row_ctx
from .visibility_condition import is_element_visible
from ..element_types.load_template_tree import _load_template_tree
def render_element_html(el, slug=None, children_map=None, ctx=None, parent_flex_direction=None):
@@ -106,7 +107,9 @@ def render_element_html(el, slug=None, children_map=None, ctx=None, parent_flex_
return _mark(f"<{tag} {_attr_string(attrs, style)}>")
content = _apply_ctx(el.get("content") or "", ctx)
child_html = _render_children(el, slug, children_map, ctx)
child_html = _render_element_type_children(el, slug, ctx) if el.get("element_type_id") else None
if child_html is None:
child_html = _render_children(el, slug, children_map, ctx)
if tag in ("ul", "ol"):
items = [line.strip() for line in content.split("\n") if line.strip()]
@@ -115,3 +118,25 @@ def render_element_html(el, slug=None, children_map=None, ctx=None, parent_flex_
safe_content = html_lib.escape(content).replace("\n", "<br>") if content else ""
return _mark(f"<{tag} {_attr_string(attrs, style)}>{safe_content}{child_html}</{tag}>")
def _render_element_type_children(el, slug, ctx):
"""Contenu d'un exemplaire d'élément de jeu posé sur un écran (voir
add_element.py, colonne element_type_id) : rechargé EN DIRECT depuis
l'écran-modèle à chaque affichage, jamais depuis d'éventuels enfants
copiés en base — exactement le même principe qu'un modèle de ligne de
Répéteur (voir _render_repeater/_load_template_tree). Modifier
l'élément de jeu dans son propre éditeur met donc à jour tous ses
exemplaires déjà posés, sur n'importe quel écran, sans avoir à les
retoucher un par un. Renvoie None (pas "") si l'élément de jeu n'a
plus de modèle valide, pour que l'appelant retombe sur le rendu
générique (d'éventuels enfants en base issus d'une version antérieure
de ce mécanisme) plutôt que d'afficher un exemplaire silencieusement
vide."""
template_tree = _load_template_tree(slug, el["element_type_id"])
if not template_tree:
return None
return "".join(
render_element_html(c, slug, template_tree["children_map"], ctx)
for c in template_tree["top"]
)