mirror of
https://github.com/kennethreitz/kjvstudy.org.git
synced 2026-06-05 23:00:16 +00:00
Add exact match redirect and family tree search integration
Family tree search: - Exact name matches now redirect directly to person page - Added search_family_tree() helper function Homepage search: - Now includes family tree people in search results - Shows up to 5 matching people with their info - Results separated into "Bible Verses" and "People in Family Tree" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+66
-2
@@ -575,25 +575,31 @@ async def custom_http_exception_handler(request: Request, exc: StarletteHTTPExce
|
||||
|
||||
@app.get("/search", response_class=HTMLResponse)
|
||||
def search_page(request: Request, q: str = Query(None, description="Search query")):
|
||||
"""Search page with results"""
|
||||
"""Search page with results (includes Bible verses and family tree)"""
|
||||
books = list(bible.iter_books())
|
||||
search_results = []
|
||||
family_tree_results = []
|
||||
is_direct_verse = False
|
||||
|
||||
if q and len(q.strip()) >= 2:
|
||||
# Search Bible verses
|
||||
search_results = perform_full_text_search(q.strip())
|
||||
# Check if this was a direct verse reference match
|
||||
if search_results and len(search_results) == 1 and search_results[0].get("score") == 100.0:
|
||||
is_direct_verse = True
|
||||
|
||||
# Also search family tree (limit to 5 results)
|
||||
family_tree_results = search_family_tree(q.strip(), limit=5)
|
||||
|
||||
return templates.TemplateResponse(
|
||||
"search.html",
|
||||
{
|
||||
"request": request,
|
||||
"query": q or "",
|
||||
"results": search_results,
|
||||
"family_tree_results": family_tree_results,
|
||||
"books": books,
|
||||
"total_results": len(search_results),
|
||||
"total_results": len(search_results) + len(family_tree_results),
|
||||
"is_direct_verse": is_direct_verse
|
||||
}
|
||||
)
|
||||
@@ -4203,6 +4209,7 @@ def family_tree_search_page(request: Request, q: str = ""):
|
||||
|
||||
# Search for people
|
||||
results = []
|
||||
exact_match_id = None
|
||||
if q:
|
||||
query_lower = q.lower()
|
||||
for person_id, person in family_tree_data.items():
|
||||
@@ -4214,6 +4221,13 @@ def family_tree_search_page(request: Request, q: str = ""):
|
||||
"birth_year": person.get("birth_year", "Unknown"),
|
||||
"death_year": person.get("death_year", "Unknown")
|
||||
})
|
||||
# Check for exact match
|
||||
if person["name"].lower() == query_lower:
|
||||
exact_match_id = person_id
|
||||
|
||||
# If there's exactly one result with an exact match, redirect to that person's page
|
||||
if exact_match_id:
|
||||
return RedirectResponse(url=f"/family-tree/person/{exact_match_id}", status_code=303)
|
||||
|
||||
return templates.TemplateResponse(
|
||||
"family_tree_search.html",
|
||||
@@ -4672,6 +4686,56 @@ def get_family_tree_data():
|
||||
return _family_tree_cache, _name_to_person_id_cache
|
||||
|
||||
|
||||
def search_family_tree(query: str, limit: Optional[int] = None) -> List[Dict]:
|
||||
"""
|
||||
Search family tree for people matching the query.
|
||||
Returns list of matching people with their info.
|
||||
"""
|
||||
results = []
|
||||
if not query or len(query.strip()) < 2:
|
||||
return results
|
||||
|
||||
try:
|
||||
# Load GEDCOM file from static folder
|
||||
static_dir = Path(__file__).parent / "static"
|
||||
gedcom_path = static_dir / "adameve.ged"
|
||||
|
||||
if not gedcom_path.exists() or not GedcomReader:
|
||||
return results
|
||||
|
||||
# Parse GEDCOM data
|
||||
family_tree_data, generations = parse_gedcom_to_tree_data(gedcom_path)
|
||||
|
||||
# Search for people
|
||||
query_lower = query.lower().strip()
|
||||
for person_id, person in family_tree_data.items():
|
||||
if query_lower in person["name"].lower():
|
||||
results.append({
|
||||
"type": "person",
|
||||
"id": person_id,
|
||||
"name": person["name"],
|
||||
"generation": person.get("generation"),
|
||||
"birth_year": person.get("birth_year", "Unknown"),
|
||||
"death_year": person.get("death_year", "Unknown"),
|
||||
"url": f"/family-tree/person/{person_id}",
|
||||
"description": f"Generation {person.get('generation', '?')} from Adam"
|
||||
})
|
||||
|
||||
# Sort by relevance (exact matches first, then alphabetically)
|
||||
results.sort(key=lambda x: (
|
||||
0 if x["name"].lower() == query_lower else 1,
|
||||
x["name"]
|
||||
))
|
||||
|
||||
# Limit results if specified
|
||||
if limit is not None:
|
||||
return results[:limit]
|
||||
return results
|
||||
|
||||
except Exception:
|
||||
return results
|
||||
|
||||
|
||||
def link_person_names_in_text(text: str) -> str:
|
||||
"""
|
||||
Find person names and verse references in text and link them.
|
||||
|
||||
@@ -112,6 +112,8 @@
|
||||
Found <strong>{{ total_results }}</strong> result{{ 's' if total_results != 1 else '' }} for "<strong>{{ query }}</strong>"
|
||||
</div>
|
||||
|
||||
{% if results %}
|
||||
<h2 style="margin-top: 2rem;">Bible Verses</h2>
|
||||
{% for result in results %}
|
||||
<article class="search-result">
|
||||
<div class="result-reference">
|
||||
@@ -120,7 +122,27 @@
|
||||
<div class="result-text">{{ result.highlighted_text | link_names | safe }}</div>
|
||||
</article>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% endif %}
|
||||
|
||||
{% if family_tree_results %}
|
||||
<h2 style="margin-top: 2rem;">People in Family Tree</h2>
|
||||
{% for result in family_tree_results %}
|
||||
<article class="search-result">
|
||||
<div class="result-reference">
|
||||
<a href="{{ result.url }}">{{ result.name }}</a>
|
||||
</div>
|
||||
<div class="result-text" style="color: #666;">
|
||||
{{ result.description }}
|
||||
{% if result.birth_year != "Unknown" or result.death_year != "Unknown" %}
|
||||
•
|
||||
{% if result.birth_year != "Unknown" %}Born {{ result.birth_year }}{% endif %}
|
||||
{% if result.death_year != "Unknown" %}{% if result.birth_year != "Unknown" %}, {% endif %}Died {{ result.death_year }}{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</article>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% elif total_results == 0 %}
|
||||
<div class="search-stats">
|
||||
<p><strong>No results found</strong> for "{{ query }}". Try different words or check your spelling.</p>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user