Static Pages
Footer/utility and editor-managed public pages that round out a journal's site chrome: related links (journal/links.php), FAQ (journal/faq.php), glossary (journal/glossary.php), the hard-copy subscription order form (journal/subscription.form.php), the sitemap (sitemap.xml.php), the RSS feed (ju.rss.php), and editor-managed dynamic CMS pages (page.php).
| Page | Status | E2E | Enhanced | Legacy Ref | Route | Roles |
|---|---|---|---|---|---|---|
| Related Links | Full | Yes | card-grid | journal/links.php | /journal/links | Public |
| FAQ | Full | Yes | accordion | journal/faq.php | /journal/faq | Public |
| Glossary | Full | Yes | search | journal/glossary.php | /journal/glossary | Public |
| Hard Copy Subscription Form | Full | Yes | validation | journal/subscription.form.php | /journal/subscription.form | Public (submitting an order requires sign-in as a journal contact; anonymous visitors are redirected to login) |
| Sitemap — Human Page | Full | — | sections | sitemap.xml.php?usr | /sitemap.xml?usr | Public |
| Sitemap — XML Feed | Full | — | sitemap-index | sitemap.xml.php | /sitemap.xml | Public |
| RSS Feed | Full | — | caching | ju.rss.php | /ju.rss | Public |
| Static Page (Custom Content) | Full | — | sanitization | page.php?ct=... | /page_{code}.html | Public (per-page: some pages require sign-in, or sign-in plus a specific role, via ju_pages.page_access/page_roles) |
| Error Page (404 / 500 / 403) | Full | — | recovery | error_page.php?code=... | /error_page[?code=500|403] | Public |
| News List | New | Yes | — | — | /en/<tenant>/news | Public |
| News Detail | New | — | — | — | /en/<tenant>/news/<code> | Public |
Features
| Feature | Status | E2E | Description |
|---|---|---|---|
| Visitor can browse the journal's curated external related links, each opening in a new tab | Full | Yes | Replaces the legacy ju_links ordered list; untitled/invalid links render as non-clickable cards instead of broken anchors. |
| Visitor can suggest a new related link via a CTA into Contact Us | New | — | Gives readers a channel to propose links without exposing an edit surface. |
| Visitor can read the journal's configured FAQs with expand/collapse | Full | Yes | Legacy flat ju_faq list ordered by faq_order becomes a keyboard-accessible disclosure accordion. |
| Visitor can reach editorial help from the FAQ page ('still need help' contact card) | New | — | Escape hatch for questions the FAQ does not answer; the hardcoded address is flagged. |
| Visitor can browse glossary terms grouped alphabetically | Full | Yes | Matches the legacy ju_glossary first-letter bucketing into an A-Z index. |
| Visitor can live-search glossary terms and filter by letter | New | — | Client-side enhancement with no legacy equivalent. |
| Signed-in journal contact can order a hard-copy subscription (volume/issue/year, subscription type, copy count) | Full | Yes | Ports the legacy ju_subscription insert flow including subscription-type choices (institute/personal/student/single copy). |
| Hard-copy form's issue dropdown cascades from the selected volume | Full | — | Volume selection drives the available issues and the derived publish year. |
| Subscriber can attach a payment receipt image to the order | Full | — | Legacy validated jpeg/jpg/png/gif uploads and stored them under the subscription receipt path. |
| Subscriber sees a sequential order ID (journal abbreviation + number) after ordering | Full | — | Legacy showed the order ID on a redirect success page; the port shows it inline with a success toast. |
| Subscriber is emailed a confirmation when the hard-copy order is recorded | Full | — | Email side-effect preserved, with warnings logged when the contact has no email on file. |
| Anonymous visitor is redirected to sign in before submitting a hard-copy order | Basic | — | The requirement survives but the UX changed from a pre-submit login redirect to a submit-time error. |
| Hard-copy form is protected against replay/abuse (session token, captcha after repeated attempts) | Dropped | — | Anti-abuse gates from the legacy form were not carried over. |
| Visitor can view a human-readable sitemap page of the journal site | Full | — | Sections reflect what the journal actually has enabled instead of the legacy hardcoded link array. |
| Search engines receive an XML sitemap of the journal's content | Full | — | Supersedes the legacy single flat urlset that inlined issues, articles, and full-text PDF URLs. |
| Search engines receive robots.txt crawler directives with a Sitemap pointer | Pending | — | Legacy robots.txt.php emitted crawler directives embedding a Sitemap: pointer; no robots route found under apps/web/app (excluded from the module's rows but still a live capability). |
| Visitor can subscribe to an RSS 2.0 feed of the journal's latest articles | Full | — | Feed items carry article titles, stripped-tag abstracts, and article permalinks as in legacy. |
| RSS feed and public routes respect the journal's second language | Full | — | Language selection moves from a cookie-setting redirect to the locale-prefixed URL. |
| Journal-authored custom CMS pages render publicly by page code | Full | — | Legacy page.php echoed raw ju_pages HTML; the port sanitizes and adds SEO metadata. |
| Restricted custom pages require sign-in, or sign-in plus a specific role, before showing content | Pending | — | Legacy page.php:38-66 gated content via ju_pages.page_access/page_roles (showing JU_WRONG_ACCESS otherwise); the new route renders publicly by code with no visible gate. |
| Link-type custom pages (page_type=2) redirect the visitor to an external URL | Pending | — | Legacy page.php:25-33 redirected to page_link (language-aware via page_link_2); no counterpart found in apps/web/lib/data/static-page-data.ts or the pages/[id] route. |
| Visitor sees a themed 404 screen with recovery actions when a journal or page is missing | Full | — | Recovery actions are an enhancement over the legacy static themed message. |
| Visitor sees a runtime/500 error screen with a Try Again action | Full | — | Framework error boundary supersedes the .htaccess ErrorDocument 500 route. |
| Visitor denied access sees a dedicated 403 screen | Pending | — | Legacy error_page.php?code=403 (reached via explicit __redirect from manager.php:50 / index.php:339) has no dedicated counterpart — access-denied currently folds into not-found/error handling. |
| Visitor can browse a paginated, filterable list of the journal's news | New | Yes | Marked New per the inventory, though the note flags it as arguably a Full port of legacy news.php (claimed by the Home module). |
| Visitor can read a single news item at a shareable permalink | New | — | Pairs the news list with a by-code detail route; same New-vs-Full ambiguity as the list. |
New pages (stage 2)
the tenant journal public news list and detail (
/news, /news/<code>) have no claiming row in any Journal module, and the Journal segment has no dedicated news module (unlike Portal, which has portal/news.html). Placed here on static-pages.html as the Journal-public auxiliary-content bucket (alongside glossary/related-links/faq). NOTE: journal/pages/news.spec.ts drives the list and journal-info's note asserts a legacy journal-news predecessor, so these are arguably Full legacy ports rather than New — flagged for Phase C (a dedicated journal/news module or re-homing as Full needs user consent).Error Page added 2026-07-02 (route-file checklist gap).
Reached two ways: automatically via the tenant root's
.htaccess ErrorDocument 404/500 directives, and explicitly via __redirect() for a 403 (manager.php:50 on access-denied, index.php:339). It renders through ThemeManager::loadPageTemplate() like any other themed screen — unlike robots.txt.php below, it has a title and themed body, so it earns a row. main/, mainm/, mainn/ each define their own plain-text ErrorDocument strings instead of routing to this file, so it is Journal-segment-only (tenant root), not shared with Portal/Super Admin.Row order
follows the legacy screen's own chrome, top to bottom: Related Links and FAQ come from the "Journal information" primary-menu group (
apps/legacy/spec/journal/journal-info-menu-configuration.md, menu_info children order: ...links, FAQ...); Glossary, the subscription form, and the sitemap link come from the base theme footer (themes/base/front/objects/footer.php, in that order); the RSS icon comes from the footer's social-icon row; and the dynamic CMS page (page.php) is last since it has no fixed nav slot — it's reached only via ad-hoc links a journal admin adds to a menu or another static page.Excluded:
news.php (list + detail) is claimed by the sibling Home module, not here.Although
news.php is a top-level public endpoint like the others in this module and was listed as a "likely anchor" to verify, apps/legacy/spec/journal/home-page-sections/home-page-news-section.md documents it explicitly as "the home-page widget plus the detail/list pages it links to" — one feature, not a footer/utility page — and the segment's Home module scope already claims "news block." Tracing confirms news.php reads $cnf->journalCode (tenant-scoped), matching that spec, not this module's remit. Excluding it here so it isn't claimed twice, per the sibling portal/news.html module's own note reaching the same conclusion independently.Sitemap split into two rows; also present in other dispatch dirs.
sitemap.xml.php branches on a request parameter (usr): present → loads the themed "Sitemap" page via ThemeManager; absent → emits a text/xml urlset document (per apps/legacy/spec/journal/Footer/sitemap.md's "Mode selection" rule), so it is split into two rows here as materially different renders of the same script. The root apps/legacy/js/sitemap.xml.php is the journal-scoped, up-to-date implementation (filters by $cnf->journalCode) and is the one referenced from the base-theme footer and from the top-level public-endpoint list in this segment's scope. Separate, older copies of sitemap.xml.php also exist in the main/, mainm/, and mainn/ dispatch dirs; the mainm/mainn copies are not journal-scoped (they enumerate every active journal and article in the database rather than filtering by the current journal), which looks like stale/inherited portal-style code rather than an intentional per-theme variant — flagging as a legacy inconsistency rather than adding extra rows for it.Excluded:
robots.txt.php.It emits a plain-text crawler-directives file (and embeds a
Sitemap: pointer to the XML feed above), but it renders no themed screen, page title, or navigable content — it isn't a "page" under this module's row-identification method, so it's called out here rather than given its own row.