Refine TalkOrigins POC navigation and resources

This commit is contained in:
welsberr 2026-04-28 19:05:36 +00:00
parent 81a7745760
commit 66378d938f
8 changed files with 183 additions and 59 deletions

View File

@ -2,7 +2,7 @@
"lang": "en",
"title": "TalkOrigins Archive: Modernized Preview",
"site_title": "TalkOrigins Archive",
"description": "A SciSiteForge proof-of-concept for the www2.talkorigins.org modernization line.",
"description": "A SciSiteForge proof-of-concept for poc1.talkorigins.org and the TalkOrigins Archive modernization line.",
"license": "CC BY-SA 4.0",
"github_url": "https://git.cns.fyi/welsberr/talkorigins-modern",
"contact_email": "feedback@talkorigins.org",
@ -35,52 +35,59 @@
]
},
"navigation": [
{ "label": "Home", "href": "/" },
{ "label": "Support", "href": "/foundation/2026-update/" },
{ "label": "Search", "href": "/search/" }
{ "label": "Start Here", "href": "#start" },
{ "label": "Key Resources", "href": "#resources" },
{ "label": "Search", "href": "https://www.talkorigins.org/search/" },
{ "label": "Roadmap", "href": "#roadmap" },
{ "label": "Support", "href": "#roadmap" }
],
"hero": {
"kicker": "Archive Preview",
"title": "A cleaner, more readable TalkOrigins Archive that still feels like the Archive.",
"lede": "Modernization is already underway: stable Archive articles, dynamic sister-site commentary, corpus-aware search, and claim-centered notebooks can coexist without collapsing into a single CMS.",
"title": "A clearer front door for the TalkOrigins Archive.",
"lede": "The modernization work keeps the Archive's stable reference role while making it easier for a first-time reader to find explanations, claims, search tools, and sister Foundation resources.",
"actions": [
{ "label": "Open the preview", "href": "/#overview", "primary": true },
{ "label": "View support update", "href": "/foundation/2026-update/", "primary": false }
{ "label": "Start with the overview", "href": "#start", "primary": true },
{ "label": "See the roadmap", "href": "#roadmap", "primary": false }
]
},
"content": {
"feature_cards": [
{
"title": "Stable Archive, Modern Access",
"body": "The preview keeps the Archive's durable explanatory role while making the reading surface responsive, easier to scan, and easier to route through search.",
"href": "/",
"meta": "modernization"
"title": "New to the topic?",
"body": "Start with readable explanations that separate the scientific issues from the rhetoric around them.",
"href": "https://www.talkorigins.org/faqs/faq-misconceptions.html",
"meta": "Archive guide",
"link_label": "Read a sample FAQ"
},
{
"title": "Foundation Search",
"body": "Search can select among TalkOrigins, TalkDesign, Panda's Thumb, Panda's Thumb MT, and the Index to Creationist Claims as separate corpora.",
"href": "/search/",
"meta": "workbench"
"title": "Looking for a specific claim?",
"body": "The Index to Creationist Claims gives readers a direct path from a familiar claim to a response and references.",
"href": "https://www.talkorigins.org/indexcc/",
"meta": "Claim index",
"link_label": "Open the Index"
},
{
"title": "Support Update",
"body": "The public update explains that modernization is already underway and that the stable Archive/dynamic commentary split is intentional.",
"href": "/foundation/2026-update/",
"meta": "public proof"
"title": "Searching across Foundation sites?",
"body": "Foundation search keeps TalkOrigins, TalkDesign, Panda's Thumb, Panda's Thumb MT, and the claim index as distinct selectable corpora.",
"href": "https://www.talkorigins.org/search/",
"meta": "Search",
"link_label": "Search the sites"
}
],
"section_cards": [
{
"title": "Featured FAQ: Misconceptions",
"body": "A representative long-form Archive article demonstrates how legacy explanatory material can be presented in the modern theme.",
"href": "/faqs/faq-misconceptions/",
"meta": "Archive article"
"href": "https://www.talkorigins.org/faqs/faq-misconceptions.html",
"meta": "Archive article",
"link_label": "Read the FAQ"
},
{
"title": "Featured Claim: CA100",
"body": "A representative Index to Creationist Claims entry shows the claim-centered path into evidence and rebuttal material.",
"href": "/indexcc/CA100/",
"meta": "Index claim"
"href": "https://www.talkorigins.org/indexcc/CA/CA100.html",
"meta": "Index claim",
"link_label": "Read the claim entry"
}
],
"bibliography_entries": [
@ -107,18 +114,18 @@
"notebooks": [
{
"id": "evidence-and-claims",
"title": "Evidence and Claims Notebook",
"summary": "A reusable study module that can connect stable Archive articles, Index to Creationist Claims entries, guided concepts, and bibliography updates.",
"audience": "self-learners, instructors, and board-reviewed site editors",
"title": "Evidence and Claims Reading Path",
"summary": "A guided path can connect stable Archive articles, Index to Creationist Claims entries, search results, and bibliography updates without hiding where each source came from.",
"audience": "interested lay readers, instructors, and site editors",
"goals": [
"Move from a claim to the relevant evidence and archive context",
"Keep stable source material separate from dynamic commentary",
"Expose provenance, citations, and review status as first-class study material"
"Show provenance, citations, and review status as part of the reading experience"
],
"apps": [
{
"title": "Public search",
"href": "/search/",
"href": "https://www.talkorigins.org/search/",
"description": "Search across Foundation corpora and the Index to Creationist Claims"
}
],
@ -126,5 +133,27 @@
"max_items": 8
}
],
"roadmap": [
{
"title": "Replace the preview placeholders with real Archive pages",
"status": "Next",
"body": "Use the modernization theme on selected high-value FAQs and claim pages so readers can evaluate actual content, not just a shell."
},
{
"title": "Promote corpus-aware Foundation search",
"status": "Next",
"body": "Make search visible from each Foundation-associated domain with Index and local-domain corpora selected by default."
},
{
"title": "Connect support messaging to visible modernization work",
"status": "Planned",
"body": "Use the proof-of-concept site to show that the Archive is being actively maintained while preserving the stable Archive and dynamic commentary split."
},
{
"title": "Add guided reading paths",
"status": "Planned",
"body": "Generalize the notebook pattern into reader-friendly paths that help users move from questions, claims, and classroom needs to reliable Archive material."
}
],
"content_sources": {}
}

View File

@ -17,6 +17,7 @@ class ContentCard:
meta: str = ""
kind: str = "feature"
source: str = ""
link_label: str = "Read More"
@dataclass(slots=True)
@ -42,6 +43,7 @@ def cards_from_config(items: list[dict[str, Any]], *, default_kind: str) -> list
meta=str(item.get("meta") or item.get("kind") or default_kind),
kind=str(item.get("kind") or default_kind),
source=str(item.get("source") or item.get("id") or title.lower().replace(" ", "-")),
link_label=str(item.get("link_label") or item.get("label") or "Read More"),
)
)
return cards

View File

@ -69,6 +69,8 @@ def _language_options_html(languages: list[dict[str, str]], current_lang: str) -
for item in languages
if item.get("coverage", True) or item.get("code") == current_lang
]
if len(visible_languages) <= 1:
return ""
return "\n".join(
f'<option value="{html_escape(item["code"])}" {"selected" if item["code"] == current_lang else ""}>{html_escape(item["name"])}</option>'
for item in visible_languages
@ -85,6 +87,41 @@ def _language_policy_html(language_policy: dict[str, Any]) -> str:
return f'<p class="language-policy-note">Planned languages: {planned_names}</p>'
def _roadmap_html(roadmap: list[dict[str, Any]], language_policy: dict[str, Any]) -> str:
items = []
for item in roadmap:
if not isinstance(item, dict):
continue
title = html_escape(item.get("title", "Roadmap item"))
body = html_escape(item.get("body", ""))
status = html_escape(item.get("status", "Planned"))
items.append(f'<li><strong>{title}</strong> <span class="meta">{status}</span><p>{body}</p></li>')
planned_languages = language_policy.get("planned_languages", [])
planned_names = ", ".join(
html_escape(item.get("name", item.get("code", "")))
for item in planned_languages
if isinstance(item, dict) and (item.get("name") or item.get("code"))
)
if planned_names:
items.append(
'<li><strong>Multilingual access</strong> <span class="meta">Planned</span>'
f'<p>Language options will appear only when reviewed coverage exists. Target languages under consideration: {planned_names}.</p></li>'
)
if not items:
return ""
return '<ul class="roadmap-list">' + "\n".join(items) + "</ul>"
def _language_selector_html(language_options: str) -> str:
if not language_options:
return ""
return (
'<select id="lang-switch" aria-label="Language" onchange="switchLanguage(this.value)">'
f"{language_options}"
"</select>"
)
def _hero_actions_html(actions: list[dict[str, Any]]) -> str:
if not actions:
return ""
@ -120,7 +157,7 @@ def _render_cards(cards: list, template_path: str | Path, lang: str) -> str:
"section_excerpt": html_escape(card.body),
"section_path": html_escape(card.source or card.title.lower().replace(" ", "-")),
"href": html_escape(card.href),
"link_label": "Open",
"link_label": html_escape(card.link_label),
},
)
)
@ -175,6 +212,7 @@ def build_site(config_file: str | Path, output_dir: str | Path) -> dict[str, Any
"page_class": html_escape(theme.page_class),
"navigation_html": _navigation_html(config.get("navigation", [])),
"language_options": _language_options_html(languages, config.get("lang", "en")),
"language_selector_html": _language_selector_html(_language_options_html(languages, config.get("lang", "en"))),
"language_policy_html": _language_policy_html(language_policy),
"hero_kicker": html_escape(hero.get("kicker", theme.display_name)),
"hero_title": html_escape(hero.get("title", config.get("title", ""))),
@ -188,6 +226,7 @@ def build_site(config_file: str | Path, output_dir: str | Path) -> dict[str, Any
for card in site_content.bibliography_entries
),
"notebook_html": render_notebooks(notebooks, site_content),
"roadmap_html": _roadmap_html(config.get("roadmap", []), language_policy),
}
page_context.update(
{

View File

@ -1,5 +1,5 @@
<article class="card feature-card">
<h3>{{ app_title }}</h3>
<p>{{ app_description }}</p>
<a href="/{{ lang }}/apps/{{ app_slug }}/" class="btn button-link">Launch App</a>
<a href="{{ href }}" class="btn button-link">{{ link_label }}</a>
</article>

View File

@ -2,6 +2,6 @@
<h3>{{ section_title }}</h3>
<p class="meta">{{ section_meta }}</p>
<p class="excerpt">{{ section_excerpt }}</p>
<button class="expand-btn btn button-link" data-src="/{{ lang }}/notebook/{{ section_path }}">Show</button>
<a href="{{ href }}" class="btn button-link">{{ link_label }}</a>
<div class="content"></div>
</div>

View File

@ -109,6 +109,7 @@ class SciSiteForgeTests(unittest.TestCase):
"body": "Corpus-aware search entry point.",
"href": "/search/",
"meta": "workbench",
"link_label": "Search",
}
],
default_kind="feature",
@ -118,6 +119,7 @@ class SciSiteForgeTests(unittest.TestCase):
self.assertEqual(cards[0].kind, "feature")
self.assertEqual(cards[0].href, "/search/")
self.assertEqual(cards[0].meta, "workbench")
self.assertEqual(cards[0].link_label, "Search")
def test_build_site_renders_selected_theme_and_content(self) -> None:
from tempfile import TemporaryDirectory
@ -236,10 +238,11 @@ class SciSiteForgeTests(unittest.TestCase):
build.build_site(config_path, out_dir)
html = (out_dir / "index.html").read_text(encoding="utf-8")
self.assertIn('<option value="en" selected>English</option>', html)
self.assertNotIn('<select id="lang-switch"', html)
self.assertNotIn('value="es"', html)
self.assertNotIn('value="fr"', html)
self.assertIn("Planned languages: Español, Français", html)
self.assertIn("Multilingual access", html)
self.assertIn("Target languages under consideration: Español, Français", html)
def test_notebook_pattern_groups_goals_apps_and_source_cards(self) -> None:
from tempfile import TemporaryDirectory

View File

@ -27,10 +27,7 @@
</div>
<nav class="top-nav" aria-label="Primary navigation">
{{ navigation_html }}
<select id="lang-switch" onchange="switchLanguage(this.value)">
{{ language_options }}
</select>
{{ language_policy_html }}
{{ language_selector_html }}
</nav>
</header>
@ -46,27 +43,27 @@
</div>
</div>
<div class="continuity-note hero-note">
<p class="eyebrow">Framework</p>
<h2>Modular, static, and reviewable</h2>
<p>This theme is intended to prove the modernization line without giving up the archive posture.</p>
<p class="eyebrow">What This Is</p>
<h2>A preview of a working modernization path</h2>
<p>The Archive remains a stable reference library. The redesign makes that library easier to read, search, and connect to sister Foundation resources.</p>
<ul class="link-list compact-list">
<li>Responsive reading</li>
<li>Reusable content blocks</li>
<li>Search and bibliography ready</li>
<li>Stable explanatory articles</li>
<li>Claim-centered entry points</li>
<li>Search across Foundation corpora</li>
</ul>
</div>
</div>
</section>
<section class="content-panel">
<h2>Feature cards</h2>
<section id="start" class="content-panel lead-panel">
<h2>Start Here</h2>
<div class="feature-grid">
{{ feature_cards_html }}
</div>
</section>
<section class="content-panel">
<h2>Notebook and app content</h2>
<section id="resources" class="content-panel resources-panel">
<h2>Key Resources</h2>
{{ notebook_html }}
<div class="section-grid">
{{ section_cards_html }}
@ -74,12 +71,17 @@
</div>
</section>
<section class="content-panel">
<h2>Bibliography</h2>
<section id="references" class="content-panel">
<h2>Reference Context</h2>
<ul class="archive-list bibliography-list">
{{ bibliography_html }}
</ul>
</section>
<section id="roadmap" class="content-panel roadmap-panel">
<h2>Roadmap</h2>
{{ roadmap_html }}
</section>
</main>
<footer class="site-footer">

View File

@ -12,7 +12,8 @@
--gold: #b18d33;
--gold-soft: #f3e4b3;
--brick-soft: #efe1dc;
--shadow: 0 22px 55px rgba(20, 33, 53, 0.1);
--shadow: 0 18px 42px rgba(20, 33, 53, 0.09);
--card-shadow: 0 8px 20px rgba(20, 33, 53, 0.06);
--max-width: 1180px;
--article-width: 760px;
}
@ -71,15 +72,21 @@ a:hover {
.article-body,
.side-card,
.site-footer,
.continuity-note,
.feature-card,
.section-card {
.continuity-note {
background: var(--panel);
border: 1px solid var(--line);
border-radius: 22px;
box-shadow: var(--shadow);
}
.feature-card,
.section-card {
background: rgba(255, 255, 255, 0.58);
border: 1px solid var(--line);
border-radius: 10px;
box-shadow: var(--card-shadow);
}
.site-header,
.site-footer,
.hero-panel,
@ -165,10 +172,12 @@ a:hover {
display: flex;
flex-wrap: wrap;
gap: 10px;
align-items: center;
}
.top-nav a,
.button-link {
.button-link,
.top-nav select {
display: inline-flex;
align-items: center;
justify-content: center;
@ -181,11 +190,16 @@ a:hover {
}
.top-nav a,
.button-link.button-link-secondary {
.button-link.button-link-secondary,
.top-nav select {
background: rgba(255, 255, 255, 0.82);
color: var(--ink);
}
.top-nav select {
font: 600 0.95rem/1.2 "Helvetica Neue", Arial, sans-serif;
}
.button-link,
.top-nav a:first-child {
background: linear-gradient(180deg, var(--blue), var(--blue-deep));
@ -292,6 +306,12 @@ a:hover {
border-top: 5px solid rgba(177, 141, 51, 0.45);
}
.resources-panel {
background:
linear-gradient(180deg, rgba(255, 255, 255, 0.98), rgba(244, 248, 252, 0.96));
border-top: 5px solid rgba(33, 79, 148, 0.34);
}
.preview-panel {
background:
linear-gradient(180deg, rgba(244, 248, 252, 0.92), rgba(255, 255, 255, 0.96));
@ -335,6 +355,15 @@ a:hover {
opacity: 0.85;
}
.feature-card .button-link,
.section-card .button-link {
min-height: 38px;
margin-top: 0.45rem;
padding: 0.55rem 0.78rem;
border-radius: 8px;
font-size: 0.88rem;
}
.lead-panel .feature-card:nth-child(4n + 1),
.direction-panel .feature-card:nth-child(3n + 1),
.section-card:nth-child(4n + 1) {
@ -525,11 +554,13 @@ a:hover {
}
.notebook-panel {
border: 1px solid var(--line);
border-radius: 8px;
border: 1px solid rgba(22, 54, 89, 0.14);
border-left: 5px solid var(--blue);
border-radius: 12px;
padding: 1.25rem;
margin: 1rem 0 1.5rem;
background: rgba(255, 255, 255, 0.84);
background:
linear-gradient(180deg, rgba(244, 248, 252, 0.9), rgba(255, 255, 255, 0.86));
}
.notebook-panel h2,
@ -556,6 +587,24 @@ a:hover {
margin-top: 0.5rem;
}
.roadmap-list,
.bibliography-list {
margin: 0;
padding-left: 1.2rem;
}
.roadmap-list li + li,
.bibliography-list li + li {
margin-top: 0.9rem;
}
.roadmap-list p {
max-width: 72ch;
margin: 0.35rem 0 0;
color: var(--muted);
line-height: 1.6;
}
a:focus-visible,
button:focus-visible {
outline: 3px solid #e5b748;