fix: use correct block name in messages template + add TPL-008 rule

- Fix messages.html: change {% block page_scripts %} to {% block extra_scripts %}
  (page_scripts doesn't exist in admin/base.html, causing JS not to load)

- Add TPL-008 architecture rule to catch invalid template block names
  This prevents silent failures where content in undefined blocks is ignored

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-21 21:50:48 +01:00
parent f2bb64cc10
commit acf8988386
3 changed files with 78 additions and 1 deletions

View File

@@ -243,6 +243,35 @@ template_rules:
file_pattern: "app/templates/**/*.html" file_pattern: "app/templates/**/*.html"
recommended_pattern: '<template x-if="items.length === 0">No items</template>' recommended_pattern: '<template x-if="items.length === 0">No items</template>'
- id: "TPL-008"
name: "Use valid block names from base templates"
severity: "error"
description: |
Templates must use block names that exist in their base template.
Using undefined blocks silently fails (content is not rendered).
Admin base blocks: title, extra_head, alpine_data, content, extra_scripts
Vendor base blocks: title, extra_head, alpine_data, content, extra_scripts
Shop base blocks: title, description, extra_head, alpine_data, content, extra_scripts
WRONG: {% block page_scripts %}...{% endblock %} (undefined)
RIGHT: {% block extra_scripts %}...{% endblock %}
pattern:
file_pattern: "app/templates/admin/**/*.html"
valid_blocks:
- "title"
- "extra_head"
- "alpine_data"
- "content"
- "extra_scripts"
forbidden_patterns:
- "{% block page_scripts %}"
- "{% block scripts %}"
- "{% block js %}"
- "{% block footer_scripts %}"
exceptions:
- "base.html"
# ============================================================================ # ============================================================================
# FRONTEND COMPONENT RULES # FRONTEND COMPONENT RULES
# ============================================================================ # ============================================================================

View File

@@ -331,6 +331,6 @@
{% endcall %} {% endcall %}
{% endblock %} {% endblock %}
{% block page_scripts %} {% block extra_scripts %}
<script src="{{ url_for('static', path='admin/js/messages.js') }}"></script> <script src="{{ url_for('static', path='admin/js/messages.js') }}"></script>
{% endblock %} {% endblock %}

View File

@@ -812,6 +812,10 @@ class ArchitectureValidator:
# TPL-007: Check empty state implementation # TPL-007: Check empty state implementation
self._check_template_empty_state(file_path, content, lines) self._check_template_empty_state(file_path, content, lines)
# TPL-008: Check for invalid block names
if is_admin:
self._check_valid_block_names(file_path, content, lines)
if is_base_or_partial: if is_base_or_partial:
return return
@@ -1053,6 +1057,50 @@ class ArchitectureValidator:
suggestion='Add <template x-if="items.length === 0">No items found</template>', suggestion='Add <template x-if="items.length === 0">No items found</template>',
) )
def _check_valid_block_names(
self, file_path: Path, content: str, lines: list[str]
):
"""TPL-008: Check that templates use valid block names from base template"""
if "noqa: tpl-008" in content.lower():
return
# Skip base templates
if file_path.name == "base.html":
return
# Valid admin template blocks
valid_blocks = {"title", "extra_head", "alpine_data", "content", "extra_scripts"}
# Common invalid block names that developers might mistakenly use
invalid_blocks = {
"page_scripts": "extra_scripts",
"scripts": "extra_scripts",
"js": "extra_scripts",
"footer_scripts": "extra_scripts",
"head": "extra_head",
"body": "content",
"main": "content",
}
import re
block_pattern = re.compile(r"{%\s*block\s+(\w+)\s*%}")
for i, line in enumerate(lines, 1):
match = block_pattern.search(line)
if match:
block_name = match.group(1)
if block_name in invalid_blocks:
self._add_violation(
rule_id="TPL-008",
rule_name="Use valid block names from base templates",
severity=Severity.ERROR,
file_path=file_path,
line_number=i,
message=f"Invalid block name '{block_name}' - this block doesn't exist in admin/base.html",
context=line.strip(),
suggestion=f"Use '{{% block {invalid_blocks[block_name]} %}}' instead",
)
def _check_pagination_macro_usage( def _check_pagination_macro_usage(
self, file_path: Path, content: str, lines: list[str] self, file_path: Path, content: str, lines: list[str]
): ):