Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .github/workflows/pages.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# Publishes the website, website/, on GitHub Pages: what OpenReliant is, the latest release's
# downloads, the roadmap and the mods, and the documentation under docs/ at /docs/. The page reads
# the release and the milestones from GitHub as it opens, so it needs publishing again only when
# it or the documentation changes.
# it or the documentation changes. Search engines find the pages through two sitemaps, the
# website's own (website/sitemap.xml) and the docs' (docs/sitemap.xml), which robots.txt at the
# root of openreliant.github.io names.
name: Pages

on:
Expand All @@ -26,7 +28,12 @@ jobs:
name: github-pages
url: ${{ steps.deploy.outputs.page_url }}
steps:
# The whole history, without the old files' contents, for the day each page of the docs last
# changed (website/docs_hooks.py).
- uses: actions/checkout@v7
with:
fetch-depth: 0
filter: blob:none
# The Predator's wire frame from the docs, drawn in the page's orange.
- run: sed 's/#7d8590/#f08a2c/g' docs/images/predator-wireframe.svg > website/predator.svg
# OpenReliant's icon (assets/icon) as the favicon of the site, its docs and the mods' site.
Expand Down
10 changes: 10 additions & 0 deletions website/contribute/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,16 @@
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Contribute · OpenReliant</title>
<meta name="description" content="How to help OpenReliant: code, testing and bug reports, mods, a star on GitHub, and sponsoring.">
<link rel="canonical" href="https://openreliant.github.io/openreliant/contribute/">
<!-- What a link to the page shows in chats and on social sites. -->
<meta property="og:type" content="website">
<meta property="og:site_name" content="OpenReliant">
<meta property="og:title" content="Contribute · OpenReliant">
<meta property="og:description" content="How to help OpenReliant: code, testing and bug reports, mods, a star on GitHub, and sponsoring.">
<meta property="og:url" content="https://openreliant.github.io/openreliant/contribute/">
<meta property="og:image" content="https://openreliant.github.io/openreliant/icon/openreliant-256.png">
<meta property="og:image:alt" content="OpenReliant's icon">
<meta name="twitter:card" content="summary">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Rajdhani:wght@500;600;700&display=swap" rel="stylesheet">
Expand Down
21 changes: 18 additions & 3 deletions website/docs-theme/main.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,24 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% if page.title and not page.is_homepage %}{{ page.title }} · {% endif %}OpenReliant docs</title>
<meta name="description" content="{{ config.site_description }}">
{%- if page.canonical_url %}<link rel="canonical" href="{{ page.canonical_url }}">{% endif %}
{#- The page's title and description, for the browser's tab and for search engines: a page's own
description is the start of its first paragraph (docs_hooks.py). #}
{%- set title = page.title ~ " · OpenReliant docs" if page.title and not page.is_homepage else "OpenReliant docs: install, play and mod StarLancer" %}
{%- set description = page.meta.description or config.site_description %}
<title>{{ title|e }}</title>
<meta name="description" content="{{ description|e }}">
{%- if page.canonical_url %}
<link rel="canonical" href="{{ page.canonical_url }}">
<meta property="og:url" content="{{ page.canonical_url }}">
{%- endif %}
{#- What a link to the page shows in chats and on social sites. #}
<meta property="og:type" content="website">
<meta property="og:site_name" content="OpenReliant">
<meta property="og:title" content="{{ title|e }}">
<meta property="og:description" content="{{ description|e }}">
<meta property="og:image" content="https://openreliant.github.io/openreliant/icon/openreliant-256.png">
<meta property="og:image:alt" content="OpenReliant's icon">
<meta name="twitter:card" content="summary">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Rajdhani:wght@500;600;700&display=swap" rel="stylesheet">
Expand Down
15 changes: 15 additions & 0 deletions website/docs-theme/sitemap.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{#- The docs' sitemap for search engines: each page's address, and the day git last changed its
file, where git says (docs_hooks.py). -#}
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
{%- for file in pages %}
{%- if not file.page.is_link and file.page.canonical_url %}
<url>
<loc>{{ file.page.canonical_url|e }}</loc>
{%- if file.page.update_date %}
<lastmod>{{ file.page.update_date }}</lastmod>
{%- endif %}
</url>
{%- endif %}
{%- endfor %}
</urlset>
78 changes: 75 additions & 3 deletions website/docs_hooks.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,36 @@
"""MkDocs hook for the website's docs: a link from a page under docs/ to a file outside it, such
as a source file, goes to that file on GitHub, and one past the repository's root, such as
../../milestones from the README, to that page of the repository on GitHub."""
"""MkDocs hooks for the website's docs.

- A link from a page under docs/ to a file outside it, such as a source file, goes to that file on
GitHub, and one past the repository's root, such as ../../milestones from the README, to that
page of the repository on GitHub.
- Each page but the first gets a description for search engines and link previews: the start of
its text, as plain text (main.html).
- Each page's date in the sitemap is the day git last changed its file (sitemap.xml), so search
engines see which pages changed. Without git's whole history, the sitemap gives no dates.
"""

import html
import os
import posixpath
import re
import subprocess

REPOSITORY = "https://github.com/OpenReliant/openreliant"
LINK = re.compile(r"(\]\()([^)\s]+)((?:\s+\"[^\"]*\")?\))")
# A paragraph or an item of a list, and a tag within one.
TEXT = re.compile(r"<(p|li)(?:\s[^>]*)?>(.*?)</\1>", re.S)
TAG = re.compile(r"<[^>]+>")

# The longest description, about what a search result shows, and the shortest that is cut at the
# end of a sentence rather than at a word. A description cut at a word ends in an ellipsis.
LONGEST_DESCRIPTION = 160
SHORTEST_DESCRIPTION = 80
ELLIPSIS = "..."


def on_pre_page(page, **_):
page.update_date = last_change(page.file.abs_src_path)
return page


def on_page_markdown(markdown, page, **_):
Expand All @@ -27,3 +51,51 @@ def rewrite(match):
return match.group(1) + url + (f"#{anchor}" if anchor else "") + match.group(3)

return LINK.sub(rewrite, markdown)


def on_page_content(content, page, **_):
if not page.is_homepage and "description" not in page.meta:
text = ""
for match in TEXT.finditer(content):
text = " ".join((text + " " + html.unescape(TAG.sub("", match.group(2)))).split())
# A text that leads into a list goes on with its items.
if len(text) >= SHORTEST_DESCRIPTION and not text.endswith(":"):
break
if text:
page.meta["description"] = shortened(text)
return content


def shortened(text):
"""`text` as a description: whole where it fits, else cut after its last sentence that fits,
or at a word."""
if len(text) <= LONGEST_DESCRIPTION:
return text
end = text.rfind(". ", 0, LONGEST_DESCRIPTION) + 1
if end >= SHORTEST_DESCRIPTION:
return text[:end]
fits = text[: LONGEST_DESCRIPTION - len(ELLIPSIS)]
return fits[: fits.rfind(" ")].rstrip(",;:") + ELLIPSIS


def git(*arguments):
"""What git prints for `arguments`, run in the website's folder; None where it fails."""
try:
return subprocess.run(
["git", *arguments], cwd=os.path.dirname(os.path.abspath(__file__)),
capture_output=True, text=True, check=True,
).stdout.strip()
except (OSError, subprocess.CalledProcessError):
return None


# Whether git has the repository's whole history. A shallow clone takes every file as changed in
# its one commit.
WHOLE_HISTORY = git("rev-parse", "--is-shallow-repository") == "false"


def last_change(path):
"""The day git last changed the file at `path`, such as 2026-10-24; None where git can't say."""
if not WHOLE_HISTORY:
return None
return git("log", "-1", "--format=%cs", "--", path) or None
43 changes: 40 additions & 3 deletions website/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,45 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>OpenReliant</title>
<meta name="description" content="OpenReliant is an open-source reimplementation of StarLancer for today's Windows, macOS and Linux, with any resolution, modern lighting and shadows, and mods. Bring your own copy of the game.">
<title>OpenReliant: play StarLancer on Windows, macOS and Linux</title>
<meta name="description" content="Play StarLancer on today's Windows, macOS and Linux. OpenReliant is a free, open-source engine for the game, with any resolution, modern lighting and mods.">
<link rel="canonical" href="https://openreliant.github.io/openreliant/">
<!-- What a link to the page shows in chats and on social sites. -->
<meta property="og:type" content="website">
<meta property="og:site_name" content="OpenReliant">
<meta property="og:title" content="OpenReliant: play StarLancer on Windows, macOS and Linux">
<meta property="og:description" content="Play StarLancer on today's Windows, macOS and Linux. OpenReliant is a free, open-source engine for the game, with any resolution, modern lighting and mods.">
<meta property="og:url" content="https://openreliant.github.io/openreliant/">
<meta property="og:image" content="https://openreliant.github.io/openreliant/icon/openreliant-256.png">
<meta property="og:image:alt" content="OpenReliant's icon">
<meta name="twitter:card" content="summary">
<!-- What OpenReliant is, for search engines: a free game application for three systems, about
StarLancer. -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "SoftwareApplication",
"name": "OpenReliant",
"url": "https://openreliant.github.io/openreliant/",
"description": "A free, open-source reimplementation of StarLancer's engine, which runs the game on today's Windows, macOS and Linux with the files from your own copy.",
"image": "https://openreliant.github.io/openreliant/icon/openreliant-256.png",
"applicationCategory": "GameApplication",
"operatingSystem": "Windows, macOS, Linux",
"offers": { "@type": "Offer", "price": "0", "priceCurrency": "USD" },
"downloadUrl": "https://github.com/OpenReliant/openreliant/releases/latest",
"softwareHelp": { "@type": "CreativeWork", "url": "https://openreliant.github.io/openreliant/docs/" },
"license": "https://www.mozilla.org/MPL/2.0/",
"sameAs": ["https://github.com/OpenReliant/openreliant"],
"about": {
"@type": "VideoGame",
"name": "StarLancer",
"genre": "Space combat",
"datePublished": "2000",
"author": [{ "@type": "Organization", "name": "Warthog" }, { "@type": "Organization", "name": "Digital Anvil" }],
"publisher": { "@type": "Organization", "name": "Microsoft" }
}
}
</script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Rajdhani:wght@500;600;700&display=swap" rel="stylesheet">
Expand Down Expand Up @@ -38,7 +75,7 @@ <h1>Open<span>Reliant</span></h1>
<a class="button" href="https://openreliant.github.io/openreliant-mods/">Mods</a>
</div>
</div>
<img src="predator.svg" alt="Wireframe of the Predator light fighter, from its model">
<img src="predator.svg" width="568" height="225" alt="Wireframe of the Predator light fighter, from its model">
</div>

<section id="story" class="story">
Expand Down
7 changes: 7 additions & 0 deletions website/sitemap.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- The website's own pages, for search engines. The docs have a sitemap of their own,
docs/sitemap.xml, and robots.txt at the root of openreliant.github.io names both. -->
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url><loc>https://openreliant.github.io/openreliant/</loc></url>
<url><loc>https://openreliant.github.io/openreliant/contribute/</loc></url>
</urlset>
Loading