Files
kjvstudy.org/kjvstudy_org/templates/parable_detail.html
T
kennethreitz 3336863a4d Improve keyboard navigation consistency across site
- Add KJVNav.initGridNav for standardized 2D grid navigation
- Migrate books.html, topics.html, resources.html to use initGridNav
- Add sidebarActive check to all templates with custom keyboard handlers
- Add [ and ] shortcuts for prev/next chapter on chapter pages
- Add [ and ] shortcuts for prev/next book on book pages
- Update accessibility page with comprehensive keyboard shortcut docs
- Add honest note about keyboard navigation complexity
- Fix sidebar nav conflicting with main content selection

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-03 01:26:09 -05:00

189 lines
6.0 KiB
HTML

{% extends "base.html" %}
{% block title %}{{ parable_name }} - Parables - KJV Study{% endblock %}
{% block description %}{{ parable.title }} - {{ parable_name }}{% endblock %}
{% block head %}
<style>
.parable-title {
font-size: 1.2rem;
color: var(--text-secondary);
font-style: italic;
margin-bottom: 1.5rem;
}
.parable-category {
font-size: 0.9rem;
color: var(--text-tertiary);
text-transform: uppercase;
letter-spacing: 0.05em;
margin-bottom: 0.5rem;
}
.parable-description {
max-width: 60%;
font-size: 1.2rem;
line-height: 1.9;
margin: 2rem 0;
}
.verse-list {
margin: 2rem 0;
}
.verse-item {
margin: 1.5rem 0;
padding-left: 1.5rem;
border-left: 3px solid var(--border-color-darker);
}
.verse-ref {
font-weight: 600;
margin-bottom: 0.75rem;
font-size: 1.1rem;
}
.verse-ref a {
color: var(--link-color);
text-decoration: none;
}
.verse-ref a:hover {
border-bottom: 1px solid var(--link-hover);
}
.verse-text {
max-width: 60%;
font-style: italic;
color: var(--text-secondary);
line-height: 1.8;
font-size: 1.1rem;
}
.intro-text {
max-width: 60%;
font-size: 1.2rem;
line-height: 1.9;
margin: 1rem 0;
}
</style>
{% endblock %}
{% block content %}
<div class="parable-category">{{ category_name }}</div>
<h1>{{ parable_name }}</h1>
<p class="parable-title">{{ parable.title }}</p>
<section>
<h2>Description</h2>
<div class="parable-description">
{{ parable.description | safe }}
</div>
</section>
<section>
<h2>Key Verses</h2>
<div class="verse-list">
{% for verse in parable.verses %}
<div class="verse-item">
<div class="verse-ref">
{% set ref_parts = verse.reference.rsplit(' ', 1) %}
{% if ref_parts|length == 2 %}
{% set book_name = ref_parts[0] %}
{% set chapter_verse = ref_parts[1] %}
{% if ':' in chapter_verse %}
{% set ch = chapter_verse.split(':')[0] %}
{% set v = chapter_verse.split(':')[1] %}
<a href="/book/{{ book_name }}/chapter/{{ ch }}/verse/{{ v }}">{{ verse.reference }}</a>
{% else %}
{{ verse.reference }}
{% endif %}
{% else %}
{{ verse.reference }}
{% endif %}
</div>
<div class="verse-text">{{ verse.text }}</div>
</div>
{% endfor %}
</div>
</section>
<section>
<p class="intro-text"><span class="newthought">Christ's parables</span> conveyed profound theological truths through familiar imagery drawn from daily life in first-century Palestine. These narratives challenged conventional wisdom, revealed the nature of God's kingdom, and called hearers to decisive response.</p>
</section>
<section>
<p><a href="/parables">← Back to all parables</a></p>
</section>
<script>
(function() {
// Include description content (p, ul, ol, blockquote, or div itself if no children), intro text, and verse items
let descElements = Array.from(document.querySelectorAll('.parable-description > p, .parable-description > ul, .parable-description > ol, .parable-description > blockquote'));
// If no block children, select the description div itself
if (descElements.length === 0) {
const descDiv = document.querySelector('.parable-description');
if (descDiv) descElements = [descDiv];
}
const elements = descElements.concat(
Array.from(document.querySelectorAll('.intro-text, .verse-item'))
);
if (elements.length === 0) return;
let selectedIndex = -1;
function selectElement(index) {
if (selectedIndex >= 0 && selectedIndex < elements.length) {
elements[selectedIndex].style.outline = '';
elements[selectedIndex].style.outlineOffset = '';
elements[selectedIndex].classList.remove('selected');
}
selectedIndex = Math.max(0, Math.min(index, elements.length - 1));
elements[selectedIndex].style.outline = '2px solid #4a7c59';
elements[selectedIndex].style.outlineOffset = '8px';
elements[selectedIndex].classList.add('selected');
elements[selectedIndex].scrollIntoView({ behavior: 'auto', block: 'center' });
}
document.addEventListener('keydown', function(e) {
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
if (KJVNav.sidebarActive) return;
if (e.key === 'ArrowDown' || e.key === 'j') {
e.preventDefault();
if (KJVNav.isSelectionOffScreen(elements, selectedIndex)) {
selectElement(KJVNav.findFirstVisibleIndex(elements));
} else {
selectElement(selectedIndex < 0 ? 0 : selectedIndex + 1);
}
} else if (e.key === 'ArrowUp' || e.key === 'k') {
e.preventDefault();
if (KJVNav.isSelectionOffScreen(elements, selectedIndex)) {
selectElement(KJVNav.findFirstVisibleIndex(elements));
} else if (selectedIndex <= 0) {
selectElement(0);
} else {
selectElement(selectedIndex - 1);
}
} else if (e.key === 'ArrowLeft' || e.key === 'h') {
e.preventDefault();
history.back();
} else if (e.key === 'Enter' && selectedIndex >= 0) {
e.preventDefault();
var el = elements[selectedIndex];
var link = el.querySelector('.verse-ref a') || el.querySelector('a');
if (link) window.location.href = link.href;
} else if (e.key === 'Escape') {
e.preventDefault();
if (selectedIndex >= 0 && selectedIndex < elements.length) {
elements[selectedIndex].style.outline = '';
elements[selectedIndex].style.outlineOffset = '';
elements[selectedIndex].classList.remove('selected');
}
selectedIndex = -1;
}
});
})();
</script>
{% endblock %}