Add glue layer support: MenuNode templates, factory registration, migration
- Templates: item.post.X → item.X (MenuNode has label/slug/feature_image directly) - factory.py: add glue.models to import loop + register_glue_handlers() at startup - alembic env.py: add glue.models to import loop - New migration: container_relations + menu_nodes tables with backfill from existing data Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -12,21 +12,21 @@
|
||||
</div>
|
||||
|
||||
{# Hidden field for selected post ID - outside form for JS access #}
|
||||
<input type="hidden" name="post_id" id="selected-post-id" value="{{ menu_item.post_id if menu_item else '' }}" />
|
||||
<input type="hidden" name="post_id" id="selected-post-id" value="{{ menu_item.container_id if menu_item else '' }}" />
|
||||
|
||||
{# Selected page display #}
|
||||
{% if menu_item %}
|
||||
<div id="selected-page-display" class="mb-3 p-3 bg-stone-50 rounded flex items-center gap-3">
|
||||
{% if menu_item.post.feature_image %}
|
||||
<img src="{{ menu_item.post.feature_image }}"
|
||||
alt="{{ menu_item.post.title }}"
|
||||
{% if menu_item.feature_image %}
|
||||
<img src="{{ menu_item.feature_image }}"
|
||||
alt="{{ menu_item.label }}"
|
||||
class="w-10 h-10 rounded-full object-cover" />
|
||||
{% else %}
|
||||
<div class="w-10 h-10 rounded-full bg-stone-200"></div>
|
||||
{% endif %}
|
||||
<div class="flex-1">
|
||||
<div class="font-medium">{{ menu_item.post.title }}</div>
|
||||
<div class="text-xs text-stone-500">{{ menu_item.post.slug }}</div>
|
||||
<div class="font-medium">{{ menu_item.label }}</div>
|
||||
<div class="text-xs text-stone-500">{{ menu_item.slug }}</div>
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
</div>
|
||||
|
||||
{# Page image #}
|
||||
{% if item.post.feature_image %}
|
||||
<img src="{{ item.post.feature_image }}"
|
||||
alt="{{ item.post.title }}"
|
||||
{% if item.feature_image %}
|
||||
<img src="{{ item.feature_image }}"
|
||||
alt="{{ item.label }}"
|
||||
class="w-12 h-12 rounded-full object-cover flex-shrink-0" />
|
||||
{% else %}
|
||||
<div class="w-12 h-12 rounded-full bg-stone-200 flex-shrink-0"></div>
|
||||
@@ -19,8 +19,8 @@
|
||||
|
||||
{# Page title #}
|
||||
<div class="flex-1 min-w-0">
|
||||
<div class="font-medium truncate">{{ item.post.title }}</div>
|
||||
<div class="text-xs text-stone-500 truncate">{{ item.post.slug }}</div>
|
||||
<div class="font-medium truncate">{{ item.label }}</div>
|
||||
<div class="text-xs text-stone-500 truncate">{{ item.slug }}</div>
|
||||
</div>
|
||||
|
||||
{# Sort order #}
|
||||
@@ -42,7 +42,7 @@
|
||||
type="button"
|
||||
data-confirm
|
||||
data-confirm-title="Delete menu item?"
|
||||
data-confirm-text="Remove {{ item.post.title }} from the menu?"
|
||||
data-confirm-text="Remove {{ item.label }} from the menu?"
|
||||
data-confirm-icon="warning"
|
||||
data-confirm-confirm-text="Yes, delete"
|
||||
data-confirm-cancel-text="Cancel"
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
hx-swap-oob="outerHTML">
|
||||
{% from 'macros/scrolling_menu.html' import scrolling_menu with context %}
|
||||
{% call(item) scrolling_menu('menu-items-container', menu_items) %}
|
||||
{% set _href = _app_slugs.get(item.post.slug, coop_url('/' + item.post.slug + '/')) %}
|
||||
{% set _href = _app_slugs.get(item.slug, coop_url('/' + item.slug + '/')) %}
|
||||
<a
|
||||
href="{{ _href }}"
|
||||
{% if item.post.slug not in _app_slugs %}
|
||||
hx-get="/{{ item.post.slug }}/"
|
||||
{% if item.slug not in _app_slugs %}
|
||||
hx-get="/{{ item.slug }}/"
|
||||
hx-target="#main-panel"
|
||||
hx-select="{{ hx_select_search }}"
|
||||
hx-swap="outerHTML"
|
||||
@@ -16,14 +16,14 @@
|
||||
{% endif %}
|
||||
class="{{styles.nav_button}}"
|
||||
>
|
||||
{% if item.post.feature_image %}
|
||||
<img src="{{ item.post.feature_image }}"
|
||||
alt="{{ item.post.title }}"
|
||||
{% if item.feature_image %}
|
||||
<img src="{{ item.feature_image }}"
|
||||
alt="{{ item.label }}"
|
||||
class="w-8 h-8 rounded-full object-cover flex-shrink-0" />
|
||||
{% else %}
|
||||
<div class="w-8 h-8 rounded-full bg-stone-200 flex-shrink-0"></div>
|
||||
{% endif %}
|
||||
<span>{{ item.post.title }}</span>
|
||||
<span>{{ item.label }}</span>
|
||||
</a>
|
||||
{% endcall %}
|
||||
</div>
|
||||
|
||||
@@ -3,19 +3,19 @@
|
||||
id="menu-items-nav-wrapper">
|
||||
{% from 'macros/scrolling_menu.html' import scrolling_menu with context %}
|
||||
{% call(item) scrolling_menu('menu-items-container', menu_items) %}
|
||||
{% set _href = _app_slugs.get(item.post.slug, coop_url('/' + item.post.slug + '/')) %}
|
||||
{% set _href = _app_slugs.get(item.slug, coop_url('/' + item.slug + '/')) %}
|
||||
<a
|
||||
href="{{ _href }}"
|
||||
class="{{styles.nav_button_less_pad}}"
|
||||
>
|
||||
{% if item.post.feature_image %}
|
||||
<img src="{{ item.post.feature_image }}"
|
||||
alt="{{ item.post.title }}"
|
||||
{% if item.feature_image %}
|
||||
<img src="{{ item.feature_image }}"
|
||||
alt="{{ item.label }}"
|
||||
class="w-8 h-8 rounded-full object-cover flex-shrink-0" />
|
||||
{% else %}
|
||||
<div class="w-8 h-8 rounded-full bg-stone-200 flex-shrink-0"></div>
|
||||
{% endif %}
|
||||
<span>{{ item.post.title }}</span>
|
||||
<span>{{ item.label }}</span>
|
||||
</a>
|
||||
{% endcall %}
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user