mirror of
https://github.com/kennethreitz/kjvstudy.org.git
synced 2026-06-05 23:00:16 +00:00
Add floating navigation sidebar with contextual drill-down
Create elegant fixed-position sidebar showing: - Current reading location (Book → Chapter → Verse) - Complete book list organized by Testament (Old/New) - Quick links to homepage, resources, and tools - Highlighted current location in navigation Features: - Sticky positioning (stays visible while scrolling) - Gradient background with subtle shadow - Organized sections: Navigation, Old Testament, New Testament, Resources - Current book/chapter/verse highlighted with bold font and left border - Context path box showing hierarchical location - Custom scrollbar styling for elegance - Responsive: hides on screens under 1400px width - Adjusts article width to accommodate sidebar on large screens Remove quick verse lookup feature: - Remove verse lookup HTML form and styling - Remove JavaScript verse parsing and navigation - Simplify base template structure Update server routes to pass context: - Add current_book to book pages - Add current_book and current_chapter to chapter pages - Add current_book, current_chapter, and current_verse to verse pages The sidebar provides intuitive navigation through the entire Bible while showing users exactly where they are in their study. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -2022,6 +2022,7 @@ def read_book(request: Request, book: str):
|
||||
"chapter_popularity": chapter_popularity,
|
||||
"chapter_explanations": chapter_explanations,
|
||||
"breadcrumbs": breadcrumbs,
|
||||
"current_book": book,
|
||||
**commentary_data
|
||||
},
|
||||
)
|
||||
@@ -2124,7 +2125,9 @@ def read_chapter(request: Request, book: str, chapter: int):
|
||||
"chapters": chapters,
|
||||
"commentaries": commentaries,
|
||||
"chapter_overview": chapter_overview,
|
||||
"breadcrumbs": breadcrumbs
|
||||
"breadcrumbs": breadcrumbs,
|
||||
"current_book": book,
|
||||
"current_chapter": chapter
|
||||
}
|
||||
)
|
||||
|
||||
@@ -2190,7 +2193,10 @@ def read_verse(request: Request, book: str, chapter: int, verse_num: int):
|
||||
"total_verses": len(verses),
|
||||
"books": books,
|
||||
"chapters": chapters,
|
||||
"breadcrumbs": breadcrumbs
|
||||
"breadcrumbs": breadcrumbs,
|
||||
"current_book": book,
|
||||
"current_chapter": chapter,
|
||||
"current_verse": verse_num
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
+176
-115
@@ -80,51 +80,6 @@
|
||||
color: #999;
|
||||
}
|
||||
|
||||
/* Elegant verse lookup */
|
||||
.verse-lookup {
|
||||
margin: 1.5rem 0 3rem 0;
|
||||
padding: 1.5rem;
|
||||
background: linear-gradient(to bottom, #fafafa 0%, #f5f5f5 100%);
|
||||
border: 1px solid #e5e5e5;
|
||||
border-radius: 2px;
|
||||
width: 55%;
|
||||
box-shadow: inset 0 1px 3px rgba(0,0,0,0.02);
|
||||
}
|
||||
|
||||
.verse-lookup-input {
|
||||
width: 100%;
|
||||
padding: 0.75rem 1rem;
|
||||
font-size: 1.1rem;
|
||||
border: 1px solid #d0d0d0;
|
||||
border-radius: 2px;
|
||||
font-family: et-book, Palatino, "Palatino Linotype", Georgia, serif;
|
||||
background: white;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.verse-lookup-input:focus {
|
||||
outline: none;
|
||||
border-color: #888;
|
||||
box-shadow: 0 0 0 3px rgba(0,0,0,0.05);
|
||||
}
|
||||
|
||||
.verse-lookup-label {
|
||||
display: block;
|
||||
margin-bottom: 0.75rem;
|
||||
font-size: 0.95rem;
|
||||
color: #555;
|
||||
font-style: italic;
|
||||
letter-spacing: 0.02em;
|
||||
}
|
||||
|
||||
.verse-lookup-error {
|
||||
display: none;
|
||||
margin-top: 0.75rem;
|
||||
color: #a33;
|
||||
font-size: 0.9rem;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* Enhanced link styling */
|
||||
a {
|
||||
color: #333;
|
||||
@@ -156,21 +111,129 @@
|
||||
font-size: 1.5rem;
|
||||
letter-spacing: 1rem;
|
||||
}
|
||||
|
||||
/* Floating Navigation Sidebar */
|
||||
.nav-sidebar {
|
||||
position: fixed;
|
||||
top: 2rem;
|
||||
right: 2rem;
|
||||
width: 280px;
|
||||
max-height: calc(100vh - 4rem);
|
||||
overflow-y: auto;
|
||||
background: linear-gradient(to bottom, #fafafa 0%, #f8f8f8 100%);
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 2px;
|
||||
padding: 1.5rem;
|
||||
font-size: 0.85rem;
|
||||
line-height: 1.6;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.08);
|
||||
}
|
||||
|
||||
.nav-sidebar::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.nav-sidebar::-webkit-scrollbar-track {
|
||||
background: #f0f0f0;
|
||||
}
|
||||
|
||||
.nav-sidebar::-webkit-scrollbar-thumb {
|
||||
background: #ccc;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.nav-sidebar h3 {
|
||||
font-size: 0.9rem;
|
||||
font-weight: 600;
|
||||
font-style: italic;
|
||||
margin: 0 0 0.75rem 0;
|
||||
padding-bottom: 0.5rem;
|
||||
border-bottom: 1px solid #ddd;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.nav-sidebar ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0 0 1.5rem 0;
|
||||
}
|
||||
|
||||
.nav-sidebar li {
|
||||
margin: 0.35rem 0;
|
||||
}
|
||||
|
||||
.nav-sidebar a {
|
||||
color: #555;
|
||||
text-decoration: none;
|
||||
border-bottom: none;
|
||||
display: block;
|
||||
padding: 0.25rem 0.5rem;
|
||||
border-radius: 2px;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.nav-sidebar a:hover {
|
||||
color: #000;
|
||||
background: rgba(0,0,0,0.05);
|
||||
}
|
||||
|
||||
.nav-sidebar a.current {
|
||||
color: #000;
|
||||
background: rgba(0,0,0,0.08);
|
||||
font-weight: 600;
|
||||
border-left: 3px solid #333;
|
||||
padding-left: 0.75rem;
|
||||
}
|
||||
|
||||
.nav-sidebar .testament-section {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.nav-sidebar .testament-title {
|
||||
font-size: 0.75rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
color: #888;
|
||||
margin-bottom: 0.5rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.nav-sidebar .book-list {
|
||||
font-size: 0.8rem;
|
||||
}
|
||||
|
||||
.nav-sidebar .context-path {
|
||||
background: #f0f0f0;
|
||||
padding: 0.75rem;
|
||||
margin-bottom: 1rem;
|
||||
border-left: 3px solid #666;
|
||||
font-size: 0.8rem;
|
||||
line-height: 1.8;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.nav-sidebar .context-path strong {
|
||||
color: #000;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* Hide sidebar on smaller screens */
|
||||
@media (max-width: 1400px) {
|
||||
.nav-sidebar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Adjust article width when sidebar is present */
|
||||
@media (min-width: 1401px) {
|
||||
article {
|
||||
max-width: calc(100% - 320px);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<article>
|
||||
<div class="verse-lookup">
|
||||
<label class="verse-lookup-label" for="verse-search">Quick Verse Lookup</label>
|
||||
<input
|
||||
type="text"
|
||||
id="verse-search"
|
||||
class="verse-lookup-input"
|
||||
placeholder="e.g., John 3:16 or Genesis 1:1"
|
||||
autocomplete="off"
|
||||
/>
|
||||
<div id="verse-lookup-error" class="verse-lookup-error"></div>
|
||||
</div>
|
||||
{% if breadcrumbs %}
|
||||
<nav class="breadcrumb">
|
||||
{% for crumb in breadcrumbs %}
|
||||
@@ -187,66 +250,64 @@
|
||||
{% block content %}{% endblock %}
|
||||
</article>
|
||||
|
||||
<!-- Floating Navigation Sidebar -->
|
||||
<nav class="nav-sidebar">
|
||||
<h3>Navigation</h3>
|
||||
|
||||
{% if current_book or current_chapter or current_verse %}
|
||||
<div class="context-path">
|
||||
{% if current_book %}
|
||||
<strong>{{ current_book }}</strong>
|
||||
{% if current_chapter %}
|
||||
<br>Chapter {{ current_chapter }}
|
||||
{% if current_verse %}
|
||||
<br>Verse {{ current_verse }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<ul>
|
||||
<li><a href="/" {% if request.url.path == "/" %}class="current"{% endif %}>Home</a></li>
|
||||
<li><a href="/verse-of-the-day">Verse of the Day</a></li>
|
||||
<li><a href="/search">Search</a></li>
|
||||
</ul>
|
||||
|
||||
{% if books %}
|
||||
<div class="testament-section">
|
||||
<div class="testament-title">Old Testament</div>
|
||||
<ul class="book-list">
|
||||
{% for book in ['Genesis', 'Exodus', 'Leviticus', 'Numbers', 'Deuteronomy', 'Joshua', 'Judges', 'Ruth', '1 Samuel', '2 Samuel', '1 Kings', '2 Kings', '1 Chronicles', '2 Chronicles', 'Ezra', 'Nehemiah', 'Esther', 'Job', 'Psalms', 'Proverbs', 'Ecclesiastes', 'Song of Solomon', 'Isaiah', 'Jeremiah', 'Lamentations', 'Ezekiel', 'Daniel', 'Hosea', 'Joel', 'Amos', 'Obadiah', 'Jonah', 'Micah', 'Nahum', 'Habakkuk', 'Zephaniah', 'Haggai', 'Zechariah', 'Malachi'] %}
|
||||
{% if book in books %}
|
||||
<li><a href="/book/{{ book }}" {% if current_book == book %}class="current"{% endif %}>{{ book }}</a></li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="testament-section">
|
||||
<div class="testament-title">New Testament</div>
|
||||
<ul class="book-list">
|
||||
{% for book in ['Matthew', 'Mark', 'Luke', 'John', 'Acts', 'Romans', '1 Corinthians', '2 Corinthians', 'Galatians', 'Ephesians', 'Philippians', 'Colossians', '1 Thessalonians', '2 Thessalonians', '1 Timothy', '2 Timothy', 'Titus', 'Philemon', 'Hebrews', 'James', '1 Peter', '2 Peter', '1 John', '2 John', '3 John', 'Jude', 'Revelation'] %}
|
||||
{% if book in books %}
|
||||
<li><a href="/book/{{ book }}" {% if current_book == book %}class="current"{% endif %}>{{ book }}</a></li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<h3>Resources</h3>
|
||||
<ul>
|
||||
<li><a href="/biblical-maps">Biblical Geography</a></li>
|
||||
<li><a href="/family-tree">Genealogies</a></li>
|
||||
<li><a href="/biblical-timeline">Timeline</a></li>
|
||||
<li><a href="/study-guides">Study Guides</a></li>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<script type="text/javascript">
|
||||
// Quick verse lookup functionality
|
||||
(function() {
|
||||
var input = document.getElementById('verse-search');
|
||||
var errorDiv = document.getElementById('verse-lookup-error');
|
||||
|
||||
function parseVerseReference(text) {
|
||||
// Match patterns like "John 3:16" or "1 John 3:16" or "Genesis 1:1"
|
||||
var pattern = /^(\d?\s*[a-z]+)\s+(\d+):(\d+)$/i;
|
||||
var match = text.trim().match(pattern);
|
||||
|
||||
if (!match) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var book = match[1].trim();
|
||||
var chapter = match[2];
|
||||
var verse = match[3];
|
||||
|
||||
// Capitalize book name properly
|
||||
book = book.split(' ')
|
||||
.map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
||||
.join(' ');
|
||||
|
||||
return {
|
||||
book: book,
|
||||
chapter: chapter,
|
||||
verse: verse
|
||||
};
|
||||
}
|
||||
|
||||
function showError(message) {
|
||||
errorDiv.textContent = message;
|
||||
errorDiv.style.display = 'block';
|
||||
}
|
||||
|
||||
function hideError() {
|
||||
errorDiv.style.display = 'none';
|
||||
}
|
||||
|
||||
input.addEventListener('keypress', function(e) {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault();
|
||||
hideError();
|
||||
|
||||
var ref = parseVerseReference(input.value);
|
||||
|
||||
if (ref) {
|
||||
// Navigate to the verse
|
||||
window.location.href = '/book/' + ref.book + '/chapter/' + ref.chapter + '/verse/' + ref.verse;
|
||||
} else {
|
||||
showError('Invalid format. Please use format like "John 3:16" or "Genesis 1:1"');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Hide error when user starts typing
|
||||
input.addEventListener('input', hideError);
|
||||
})();
|
||||
|
||||
// Gauges analytics
|
||||
var _gauges = _gauges || [];
|
||||
(function() {
|
||||
|
||||
Reference in New Issue
Block a user