Add siblings to family tree/genealogy person pages

Enhancements:
- Added siblings field to person data structure
- Calculate siblings by finding people who share parents
- Display siblings section on person pages with count
- Siblings shown between parents and children sections
- Includes same metadata as other relationships (generation, lifespan)

Implementation:
- Third pass in parse_gedcom_to_tree_data() to calculate siblings
- Uses set to avoid duplicates from multiple shared parents
- Template displays sibling count and links to sibling pages

Example: Cain, Abel, and Seth now show as siblings on each other's pages.

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-21 19:28:51 -05:00
parent b0d136ae09
commit 0ed1bcdb62
2 changed files with 38 additions and 0 deletions
+18
View File
@@ -3649,6 +3649,7 @@ def parse_gedcom_to_tree_data(gedcom_path):
"description": description,
"children": [],
"parents": [],
"siblings": [],
"spouse": None,
"verses": all_verses,
"birth_year": birth_year,
@@ -3695,6 +3696,23 @@ def parse_gedcom_to_tree_data(gedcom_path):
if wife_id not in tree_data[child_id]["parents"]:
tree_data[child_id]["parents"].append(wife_id)
# Third pass: calculate siblings
# Siblings are people who share at least one parent
for person_id, person in tree_data.items():
siblings_set = set()
# Find all people who share a parent with this person
for parent_id in person["parents"]:
if parent_id in tree_data:
# Get all children of this parent
for sibling_id in tree_data[parent_id]["children"]:
# Don't include the person themselves
if sibling_id != person_id:
siblings_set.add(sibling_id)
# Convert set to list and store
person["siblings"] = list(siblings_set)
# Calculate generations using BFS from root people (those with no parents)
generations = {}
for person_id, person in tree_data.items():
@@ -164,6 +164,26 @@
</div>
{% endif %}
{% if person.siblings|length > 0 %}
<div class="relationships-section">
<h2>Siblings ({{ person.siblings|length }})</h2>
<div class="relationship-list">
{% for sibling_id in person.siblings %}
{% if sibling_id in family_tree_data %}
<div class="relationship-item">
<span class="relationship-name"><a href="/family-tree/person/{{ sibling_id }}">{{ family_tree_data[sibling_id].name }}</a></span>
{% if family_tree_data[sibling_id].generation or family_tree_data[sibling_id].age_at_death != "Unknown" %}
<span class="relationship-meta">
{% if family_tree_data[sibling_id].generation %}generation {{ family_tree_data[sibling_id].generation }}{% endif %}{% if family_tree_data[sibling_id].age_at_death != "Unknown" %}{% if family_tree_data[sibling_id].generation %}, {% endif %}lived {{ family_tree_data[sibling_id].age_at_death }}{% endif %}
</span>
{% endif %}
</div>
{% endif %}
{% endfor %}
</div>
</div>
{% endif %}
{% if person.children|length > 0 %}
<div class="relationships-section">
<h2>Children ({{ person.children|length }})</h2>