From 81a774576011bbbef9a1a40d385e1bc8c4a833ca Mon Sep 17 00:00:00 2001 From: welsberr Date: Tue, 28 Apr 2026 18:01:19 +0000 Subject: [PATCH] Enrich TalkOrigins modern example content --- examples/talkorigins-modern.site.json | 65 +++++++++++++++++++++++++-- scisiteforge/__init__.py | 1 + scisiteforge/content.py | 19 ++++++++ scripts/build.py | 7 +++ tests/test_scisiteforge.py | 20 ++++++++- 5 files changed, 107 insertions(+), 5 deletions(-) diff --git a/examples/talkorigins-modern.site.json b/examples/talkorigins-modern.site.json index dd92e43..e2bfa14 100644 --- a/examples/talkorigins-modern.site.json +++ b/examples/talkorigins-modern.site.json @@ -2,9 +2,10 @@ "lang": "en", "title": "TalkOrigins Archive: Modernized Preview", "site_title": "TalkOrigins Archive", + "description": "A SciSiteForge proof-of-concept for the www2.talkorigins.org modernization line.", "license": "CC BY-SA 4.0", - "github_url": "https://example.invalid/talkorigins-modern", - "contact_email": "admin@example.invalid", + "github_url": "https://git.cns.fyi/welsberr/talkorigins-modern", + "contact_email": "feedback@talkorigins.org", "theme": "talkorigins-modern", "languages": [ { "code": "en", "name": "English", "coverage": true }, @@ -41,10 +42,66 @@ "hero": { "kicker": "Archive Preview", "title": "A cleaner, more readable TalkOrigins Archive that still feels like the Archive.", - "lede": "Use this preset as the proving ground for the www2.talkorigins.org modernization line.", + "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.", "actions": [ { "label": "Open the preview", "href": "/#overview", "primary": true }, - { "label": "View the framework", "href": "https://example.invalid/scisiteforge", "primary": false } + { "label": "View support update", "href": "/foundation/2026-update/", "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": "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": "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" + } + ], + "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" + }, + { + "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" + } + ], + "bibliography_entries": [ + { + "title": "TalkOrigins Archive", + "body": "Stable explanatory articles and FAQs for recurring creation/evolution controversy topics.", + "href": "https://www.talkorigins.org/", + "meta": "primary corpus" + }, + { + "title": "Index to Creationist Claims", + "body": "Claim-indexed rebuttal and reference material used as a cross-site search and notebook anchor.", + "href": "https://www.talkorigins.org/indexcc/", + "meta": "claim index" + }, + { + "title": "Panda's Thumb MT Archive", + "body": "Definitive corpus for the Movable Type-era Panda's Thumb archive, distinct from the broader scraped corpus.", + "href": "https://pandasthumb.net/", + "meta": "sister corpus" + } ] }, "notebooks": [ diff --git a/scisiteforge/__init__.py b/scisiteforge/__init__.py index e0da76f..d86069b 100644 --- a/scisiteforge/__init__.py +++ b/scisiteforge/__init__.py @@ -1,4 +1,5 @@ from .content import ( + cards_from_config, ContentCard, SiteContent, load_citegeist_cards, diff --git a/scisiteforge/content.py b/scisiteforge/content.py index 953e34a..e15add6 100644 --- a/scisiteforge/content.py +++ b/scisiteforge/content.py @@ -28,6 +28,25 @@ class SiteContent: notes: list[str] = field(default_factory=list) +def cards_from_config(items: list[dict[str, Any]], *, default_kind: str) -> list[ContentCard]: + cards: list[ContentCard] = [] + for item in items: + if not isinstance(item, dict): + continue + title = str(item.get("title") or item.get("name") or "Item") + cards.append( + ContentCard( + title=title, + body=str(item.get("body") or item.get("description") or item.get("summary") or ""), + href=str(item.get("href") or item.get("url") or ""), + 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(" ", "-")), + ) + ) + return cards + + def _first_paragraph(text: str) -> str: paragraphs = [chunk.strip() for chunk in re.split(r"\n\s*\n", text) if chunk.strip()] return paragraphs[0] if paragraphs else text.strip() diff --git a/scripts/build.py b/scripts/build.py index 601794f..4de5e4e 100644 --- a/scripts/build.py +++ b/scripts/build.py @@ -13,6 +13,7 @@ sys.path.insert(0, str(Path(__file__).resolve().parents[1])) from scisiteforge.config import DEFAULT_THEME, load_config, save_config from scisiteforge.content import ( SiteContent, + cards_from_config, load_citegeist_cards, load_didactopus_cards, load_doclift_cards, @@ -57,6 +58,7 @@ def _prompt_for_config() -> dict[str, Any]: ], }, "content_sources": {}, + "content": {}, "notebooks": [], } @@ -144,6 +146,11 @@ def build_site(config_file: str | Path, output_dir: str | Path) -> dict[str, Any site_content.feature_cards.extend(load_didactopus_cards(source)) if source := content_sources.get("bibliography"): site_content.bibliography_entries.extend(load_citegeist_cards(source)) + inline_content = config.get("content", {}) + site_content.feature_cards.extend(cards_from_config(inline_content.get("feature_cards", []), default_kind="feature")) + site_content.section_cards.extend(cards_from_config(inline_content.get("section_cards", []), default_kind="section")) + site_content.app_cards.extend(cards_from_config(inline_content.get("app_cards", []), default_kind="app")) + site_content.bibliography_entries.extend(cards_from_config(inline_content.get("bibliography_entries", []), default_kind="bibliography")) notebooks = load_notebooks(config) languages = config.get("languages", [{"code": config.get("lang", "en"), "name": "English", "coverage": True}]) diff --git a/tests/test_scisiteforge.py b/tests/test_scisiteforge.py index 7e5ae42..80b1abd 100644 --- a/tests/test_scisiteforge.py +++ b/tests/test_scisiteforge.py @@ -13,7 +13,7 @@ sys.path.insert(0, str(ROOT / "scripts")) import build import translate_site -from scisiteforge.content import SiteContent, load_citegeist_cards, load_didactopus_cards, load_doclift_cards, load_groundrecall_cards +from scisiteforge.content import SiteContent, cards_from_config, load_citegeist_cards, load_didactopus_cards, load_doclift_cards, load_groundrecall_cards from scisiteforge.notebook import load_notebooks, render_notebooks from scisiteforge.themes import get_theme, materialize_theme from scisiteforge.translations import GenieHiveTranslator, TranslationConfig @@ -101,6 +101,24 @@ class SciSiteForgeTests(unittest.TestCase): self.assertEqual(didactopus_cards[0].title, "Prior") self.assertEqual(citegeist_cards[0].title, "A Study") + def test_inline_config_cards_can_seed_example_content(self) -> None: + cards = cards_from_config( + [ + { + "title": "Foundation Search", + "body": "Corpus-aware search entry point.", + "href": "/search/", + "meta": "workbench", + } + ], + default_kind="feature", + ) + + self.assertEqual(cards[0].title, "Foundation Search") + self.assertEqual(cards[0].kind, "feature") + self.assertEqual(cards[0].href, "/search/") + self.assertEqual(cards[0].meta, "workbench") + def test_build_site_renders_selected_theme_and_content(self) -> None: from tempfile import TemporaryDirectory