Files
kennethreitz 324143e566 Enhance Easter eggs with scripture quotes and links
Add actual verse content and clickable links to Easter eggs:
- Enoch: Show Jude 1:14-15 quote with link
- Jasher: Link to Joshua 10:13 and 2 Samuel 1:18

Makes the 404 page more educational and engaging.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-23 23:28:19 -05:00

493 lines
16 KiB
HTML

{% extends "base.html" %}
{% block title %}
{% if status_code == 404 %}
Page Not Found - KJV Study
{% else %}
Error {{ status_code }} - KJV Study
{% endif %}
{% endblock %}
{% block description %}The requested page could not be found. Use our search to find Bible passages, topics, study guides, and more.{% endblock %}
{% block head %}
<style>
.error-page {
max-width: 70%;
margin: 0 auto;
}
.error-header {
margin: 3rem 0 2rem;
}
.error-code {
font-size: 6rem;
font-weight: 300;
color: var(--text-secondary);
line-height: 1;
margin: 0;
font-variant-numeric: oldstyle-nums;
}
.error-title {
font-size: 2.5rem;
font-weight: 400;
margin: 1rem 0 0.5rem;
line-height: 1.2;
}
.error-verse {
max-width: 60%;
font-size: 1.3rem;
line-height: 1.9;
font-style: italic;
color: var(--text-secondary);
margin: 2rem 0;
padding-left: 1.5rem;
border-left: 3px solid var(--border-color-darker);
}
.error-verse-ref {
display: block;
margin-top: 0.5rem;
font-style: normal;
font-weight: 600;
font-size: 1rem;
}
.error-verse-ref a {
color: var(--link-color);
text-decoration: none;
}
.error-verse-ref a:hover {
border-bottom: 1px solid var(--link-color);
}
.error-explanation {
max-width: 60%;
font-size: 1.2rem;
line-height: 1.9;
margin: 2rem 0;
}
.search-container {
max-width: 60%;
margin: 3rem 0;
padding: 2rem;
background: var(--code-bg);
border: 1px solid var(--border-color);
}
.search-container h2 {
font-size: 1.3rem;
font-weight: 600;
margin: 0 0 1rem;
}
.search-box {
width: 100%;
padding: 0.75rem 1rem;
font-size: 1.1rem;
border: 2px solid var(--border-color-darker);
background: var(--bg-color);
color: var(--text-color);
font-family: inherit;
border-radius: 2px;
}
.search-box:focus {
outline: none;
border-color: var(--link-color);
}
.search-examples {
margin-top: 0.75rem;
font-size: 0.9rem;
color: var(--text-secondary);
}
.search-examples code {
background: var(--bg-color);
padding: 0.15rem 0.4rem;
border: 1px solid var(--border-color);
font-size: 0.85rem;
}
.suggestions-section {
margin: 2rem 0;
padding: 1.5rem;
background: #fffaed;
border-left: 3px solid #d4a574;
}
.suggestions-section h3 {
font-size: 1.2rem;
font-weight: 600;
margin: 0 0 1rem;
color: #8b6914;
}
.suggestion-text {
margin: 0.5rem 0;
}
.suggestion-text a {
color: var(--link-color);
text-decoration: none;
font-weight: 600;
}
.suggestion-text a:hover {
border-bottom: 1px solid var(--link-color);
}
.helpful-links {
margin: 3rem 0;
}
.helpful-links h2 {
font-size: 1.5rem;
font-weight: 600;
margin: 0 0 1.5rem;
}
.links-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1rem;
max-width: 60%;
}
.help-link {
padding: 1rem;
border: 1px solid var(--border-color);
text-decoration: none;
color: var(--text-color);
display: block;
transition: all 0.2s;
}
.help-link:hover {
border-color: var(--link-color);
background: var(--code-bg);
}
.help-link-title {
font-weight: 600;
margin-bottom: 0.25rem;
color: var(--link-color);
}
.help-link-desc {
font-size: 0.9rem;
color: var(--text-secondary);
}
.go-back {
margin: 2rem 0;
}
.go-back a {
color: var(--link-color);
text-decoration: none;
font-weight: 600;
}
.go-back a:hover {
border-bottom: 1px solid var(--link-color);
}
</style>
{% endblock %}
{% block content %}
<article class="error-page">
{% if status_code == 404 %}
<header class="error-header">
<p class="error-code">404</p>
<h1 class="error-title">The Page You Seek Cannot Be Found</h1>
</header>
<blockquote class="error-verse">
What man of you, having an hundred sheep, if he lose one of them, doth not leave the ninety and nine in the wilderness, and go after that which is lost, until he find it?
<span class="error-verse-ref">
<a href="/book/Luke/chapter/15/verse/4">Luke 15:4</a>
</span>
</blockquote>
<div id="url-suggestions"></div>
<section class="search-container">
<h2>Search the Scriptures</h2>
<form action="/search" method="get" onsubmit="handleSearch(event)">
<input type="text"
name="q"
class="search-box"
placeholder="Search verses, topics, or enter a reference like 'John 3:16'"
autofocus>
</form>
<div class="search-examples">
Try: <code>John 3:16</code>, <code>faith</code>, <code>Psalm 23</code>, or <code>salvation</code>
</div>
</section>
<section class="helpful-links">
<h2>Continue Your Study</h2>
<div class="links-grid">
<a href="/" class="help-link">
<div class="help-link-title">Browse Books</div>
<div class="help-link-desc">Old and New Testament</div>
</a>
<a href="/topics" class="help-link">
<div class="help-link-title">Topical Index</div>
<div class="help-link-desc">Study by subject</div>
</a>
<a href="/study-guides" class="help-link">
<div class="help-link-title">Study Guides</div>
<div class="help-link-desc">Theological essays</div>
</a>
<a href="/biblical-prophets" class="help-link">
<div class="help-link-title">Biblical Prophets</div>
<div class="help-link-desc">Messengers of God</div>
</a>
<a href="/biblical-angels" class="help-link">
<div class="help-link-title">Biblical Angels</div>
<div class="help-link-desc">Heavenly beings</div>
</a>
<a href="/biblical-covenants" class="help-link">
<div class="help-link-title">Biblical Covenants</div>
<div class="help-link-desc">God's promises</div>
</a>
</div>
</section>
<section class="go-back">
<p><a href="javascript:history.back()">← Return to previous page</a> or <a href="/">go to homepage</a></p>
</section>
{% else %}
{# Other error codes #}
<header class="error-header">
<p class="error-code">{{ status_code }}</p>
<h1 class="error-title">An Error Has Occurred</h1>
</header>
<section class="error-explanation">
<p>{{ detail or "An unexpected error occurred. Please try again or return to the homepage." }}</p>
</section>
<section class="go-back">
<p><a href="javascript:history.back()">← Return to previous page</a> or <a href="/">go to homepage</a></p>
</section>
{% endif %}
</article>
<script>
document.addEventListener('DOMContentLoaded', function() {
const path = window.location.pathname;
const suggestionsDiv = document.getElementById('url-suggestions');
// Try to parse the URL and suggest corrections
const suggestions = [];
// Canonical KJV books
const bookNames = [
'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',
'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'
];
// Apocryphal/non-canonical books (Easter eggs!)
const apocryphalBooks = {
'enoch': 'The Book of Enoch is not part of the Protestant canon, though it is referenced in <a href="/book/Jude/chapter/1/verse/14">Jude 1:14-15</a>: "Enoch also, the seventh from Adam, prophesied of these, saying, Behold, the Lord cometh with ten thousands of his saints."',
'tobit': 'The Book of Tobit is part of the Catholic Deuterocanon but not included in Protestant Bibles.',
'judith': 'The Book of Judith is part of the Catholic Deuterocanon but not included in Protestant Bibles.',
'wisdom': 'The Wisdom of Solomon is part of the Catholic Deuterocanon but not included in Protestant Bibles.',
'sirach': 'The Book of Sirach (Ecclesiasticus) is part of the Catholic Deuterocanon but not included in Protestant Bibles.',
'baruch': 'The Book of Baruch is part of the Catholic Deuterocanon but not included in Protestant Bibles.',
'maccabees': 'The Books of Maccabees are part of the Catholic Deuterocanon but not included in Protestant Bibles.',
'1maccabees': 'First Maccabees is part of the Catholic Deuterocanon but not included in Protestant Bibles.',
'2maccabees': 'Second Maccabees is part of the Catholic Deuterocanon but not included in Protestant Bibles.',
'thomas': 'The Gospel of Thomas is a Gnostic text not accepted as canonical by any major Christian tradition.',
'jasher': 'The Book of Jasher is mentioned in <a href="/book/Joshua/chapter/10/verse/13">Joshua 10:13</a> and <a href="/book/2 Samuel/chapter/1/verse/18">2 Samuel 1:18</a>, but the original text is lost. Modern versions are of disputed authenticity.',
'jubilees': 'The Book of Jubilees is considered canonical only by the Ethiopian Orthodox Church.'
};
// Common misspellings and their corrections
const commonMisspellings = {
'philipians': 'Philippians',
'philippeans': 'Philippians',
'collossians': 'Colossians',
'colosians': 'Colossians',
'thesselonians': 'Thessalonians',
'galations': 'Galatians',
'corintheans': 'Corinthians',
'ephesans': 'Ephesians',
'eclesiastes': 'Ecclesiastes',
'ecclesiates': 'Ecclesiastes',
'deutronomy': 'Deuteronomy',
'dueteronomy': 'Deuteronomy',
'levitcus': 'Leviticus',
'isiah': 'Isaiah',
'isaiah': 'Isaiah',
'jeremia': 'Jeremiah',
'ezekial': 'Ezekiel',
'revalation': 'Revelation',
'revelations': 'Revelation',
'psalm': 'Psalms',
'songs of solomon': 'Song of Solomon',
'song of songs': 'Song of Solomon'
};
// Check for apocryphal books first (must be in /book/ path)
const pathLower = path.toLowerCase();
if (pathLower.includes('/book/')) {
for (const [apocBook, explanation] of Object.entries(apocryphalBooks)) {
if (pathLower.includes('/book/' + apocBook) || pathLower.includes('/book/' + apocBook.replace(/\s/g, ''))) {
suggestions.push({
text: explanation,
url: null,
isInfo: true
});
break;
}
}
}
// If no apocryphal book found, check for canonical books or misspellings
if (suggestions.length === 0) {
// Check for common misspellings
let correctedBook = null;
for (const [misspelling, correction] of Object.entries(commonMisspellings)) {
if (pathLower.includes(misspelling)) {
correctedBook = correction;
break;
}
}
// Check for book references in the URL (exact or corrected)
for (const book of bookNames) {
const bookToCheck = correctedBook || book;
if (pathLower.includes(bookToCheck.toLowerCase().replace(/\s/g, ''))) {
// Try to extract chapter and verse
const chapterMatch = path.match(/chapter[\/\-]?(\d+)/i);
const verseMatch = path.match(/verse[\/\-]?(\d+)/i);
if (correctedBook) {
// Show misspelling correction
if (chapterMatch) {
const chapter = chapterMatch[1];
if (verseMatch) {
const verse = verseMatch[1];
suggestions.push({
text: `Did you mean ${correctedBook} ${chapter}:${verse}?`,
url: `/book/${correctedBook}/chapter/${chapter}/verse/${verse}`
});
} else {
suggestions.push({
text: `Did you mean ${correctedBook} chapter ${chapter}?`,
url: `/book/${correctedBook}/chapter/${chapter}`
});
}
} else {
suggestions.push({
text: `Did you mean the book of ${correctedBook}?`,
url: `/book/${correctedBook}`
});
}
} else if (book === bookToCheck) {
// Exact match found
if (chapterMatch) {
const chapter = chapterMatch[1];
if (verseMatch) {
const verse = verseMatch[1];
suggestions.push({
text: `Did you mean ${book} ${chapter}:${verse}?`,
url: `/book/${book}/chapter/${chapter}/verse/${verse}`
});
} else {
suggestions.push({
text: `Did you mean ${book} chapter ${chapter}?`,
url: `/book/${book}/chapter/${chapter}`
});
}
} else {
suggestions.push({
text: `Did you mean the book of ${book}?`,
url: `/book/${book}`
});
}
}
break;
}
}
}
// Check for common misspellings or old URLs
if (path.includes('/verse-of-the-day')) {
suggestions.push({
text: 'Looking for the Verse of the Day?',
url: '/'
});
}
if (path.includes('/search')) {
suggestions.push({
text: 'Try the search feature above',
url: null
});
}
// Display suggestions if any
if (suggestions.length > 0 && suggestionsDiv) {
let html = '<section class="suggestions-section"><h3>Perhaps You Were Looking For...</h3>';
for (const suggestion of suggestions) {
if (suggestion.url) {
html += `<p class="suggestion-text"><a href="${suggestion.url}">${suggestion.text}</a></p>`;
} else {
html += `<p class="suggestion-text">${suggestion.text}</p>`;
}
}
html += '</section>';
suggestionsDiv.innerHTML = html;
}
});
function handleSearch(event) {
event.preventDefault();
const query = event.target.querySelector('input[name="q"]').value.trim();
if (!query) return;
// Check if query looks like a verse reference (e.g., "John 3:16")
const versePattern = /^(\d?\s?[A-Za-z]+(?:\s+[A-Za-z]+)?)\s+(\d+)(?::(\d+))?$/;
const match = query.match(versePattern);
if (match) {
const book = match[1].trim();
const chapter = match[2];
const verse = match[3];
if (verse) {
window.location.href = `/book/${book}/chapter/${chapter}/verse/${verse}`;
} else {
window.location.href = `/book/${book}/chapter/${chapter}`;
}
} else {
// Regular search
window.location.href = `/search?q=${encodeURIComponent(query)}`;
}
}
</script>
{% endblock %}