feat: import VPC plant by pasting URL directly in search

slug_from_query() detects VPC URLs and bare slugs (must contain a hyphen
to avoid treating single search words as slugs). When matched, the search
bypasses the keyword search and shows the plant directly as a VPC result.
Updated search hint text to make this discoverable.

Fixes: VPC search by English name (e.g. "crowfoot") is a VPC limitation —
their search only indexes Latin titles, not custom fields like Engelse naam.
The URL paste workflow is the reliable workaround.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Stephan Kerkman 2026-05-28 20:20:06 +02:00
parent a48ee9e73d
commit f594105311
3 changed files with 37 additions and 16 deletions

View file

@ -76,6 +76,20 @@ def _slug_from_url(url):
return m.group(1) if m else ''
def slug_from_query(query):
"""Return a VPC slug if query is a VPC URL or bare slug, else empty string."""
query = query.strip()
# Full URL containing /soorten/
slug = _slug_from_url(query)
if slug:
return slug
# Bare slug: lowercase, hyphens, no spaces, must contain at least one hyphen
# (single words are normal search terms, not slugs)
if re.fullmatch(r'[a-z0-9][a-z0-9\-]+', query) and '-' in query:
return query
return ''
def search_species(query):
"""
Search VPC and return up to 8 result dicts:

View file

@ -2,7 +2,7 @@
{% block title %}Add Plant — PlantDB{% endblock %}
{% block content %}
<h5 class="mb-3">Add a plant</h5>
<p class="text-muted small">Search for the species to auto-fill care info, or skip to enter details manually.</p>
<p class="text-muted small">Search by name, or paste a VPC URL to import a specific plant directly.</p>
<div class="input-group mb-2">
<input

View file

@ -21,6 +21,13 @@ def species_search(request):
error = None
if len(q) >= 2:
# If the query looks like a VPC URL or slug, skip the search and show
# it directly as a single importable result.
vpc_slug = vpc_service.slug_from_query(q)
if vpc_slug:
vpc_results = [{'slug': vpc_slug, 'common_name': vpc_slug.replace('-', ' ').title(),
'scientific_name': '', 'thumbnail_url': '', 'source': 'vpc'}]
else:
def _run_perenual():
try:
return perenual_search(q), None