From 539303b8f6241530a6e7990784cc263429d55bba Mon Sep 17 00:00:00 2001 From: OpenClaw Sub-agent Date: Sun, 2 Aug 2026 17:48:25 +1000 Subject: [PATCH] feat(link form): TEMPLATE becomes its own type with dedicated tab/fields MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - models: LinkType gains TEMPLATE (migration 0054, choices only) - link_form: 4 tabs — Link / 🔧 Template / Custom / ⚡ Action; each type shows only its own fields: Template tab owns the Sketch builder, Link tab is a plain URL, Custom owns the markdown editor, Action owns the Discord card + message template; per-type descriptions; tab colors blue/purple/ green/purple - Editing a legacy LINK with {param} in URL auto-switches to Template tab (and saving migrates it to TEMPLATE type) - badges (row/detail/search cards) recognize TEMPLATE type; detail page shows Original URL for TEMPLATE too - forms: TEMPLATE requires original_url --- links/forms.py | 2 + .../migrations/0054_add_template_link_type.py | 18 ++ links/models.py | 1 + links/templates/links/_link_row.html | 2 +- links/templates/links/link_detail.html | 4 +- links/templates/links/link_form.html | 156 ++++++++---------- links/templates/links/link_list.html | 1 + links/views.py | 2 + 8 files changed, 100 insertions(+), 86 deletions(-) create mode 100644 links/migrations/0054_add_template_link_type.py diff --git a/links/forms.py b/links/forms.py index ad33f32..c70a622 100644 --- a/links/forms.py +++ b/links/forms.py @@ -130,6 +130,8 @@ class LinkForm(forms.ModelForm): if link_type == Link.LinkType.LINK and not original_url: raise forms.ValidationError(_("Original URL is required for Link type.")) + elif link_type == Link.LinkType.TEMPLATE and not original_url: + raise forms.ValidationError(_("Original URL is required for Template type.")) elif link_type == Link.LinkType.CUSTOM and not text: raise forms.ValidationError(_("Text is required for Custom type.")) elif link_type == Link.LinkType.ACTION: diff --git a/links/migrations/0054_add_template_link_type.py b/links/migrations/0054_add_template_link_type.py new file mode 100644 index 0000000..8e9f2a2 --- /dev/null +++ b/links/migrations/0054_add_template_link_type.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.12 on 2026-08-02 07:46 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('links', '0053_ask_as_action_link'), + ] + + operations = [ + migrations.AlterField( + model_name='link', + name='link_type', + field=models.CharField(choices=[('LINK', 'Link'), ('TEMPLATE', 'Template'), ('CUSTOM', 'Custom'), ('ACTION', 'Action')], default='LINK', max_length=10), + ), + ] diff --git a/links/models.py b/links/models.py index 763ba69..3c5de33 100644 --- a/links/models.py +++ b/links/models.py @@ -19,6 +19,7 @@ logger = logging.getLogger(__name__) class Link(models.Model): class LinkType(models.TextChoices): LINK = 'LINK', _('Link') + TEMPLATE = 'TEMPLATE', _('Template') CUSTOM = 'CUSTOM', _('Custom') ACTION = 'ACTION', _('Action') diff --git a/links/templates/links/_link_row.html b/links/templates/links/_link_row.html index 72cca5d..4a1ba34 100644 --- a/links/templates/links/_link_row.html +++ b/links/templates/links/_link_row.html @@ -7,7 +7,7 @@ {{ link.alias }} - {% if '{' in link.original_url and '}' in link.original_url %} + {% if link.link_type == 'TEMPLATE' or '{' in link.original_url|default:'' and '}' in link.original_url|default:'' %} {% trans "Template" %} {% elif link.link_type == 'LINK' %} {% trans "Link" %} diff --git a/links/templates/links/link_detail.html b/links/templates/links/link_detail.html index 611e2d6..8c3316c 100644 --- a/links/templates/links/link_detail.html +++ b/links/templates/links/link_detail.html @@ -10,7 +10,7 @@