Skip to content

Commit

Permalink
ENH Prepare codebase to migrate to GitHub Pages
Browse files Browse the repository at this point in the history
  • Loading branch information
GuySartorelli committed Dec 4, 2024
1 parent bfe0238 commit 504e2fe
Show file tree
Hide file tree
Showing 12 changed files with 244 additions and 29 deletions.
61 changes: 61 additions & 0 deletions .github/workflows/deploy-gh-pages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
name: Deploy to GitHub pages

on:
push:
branches: [ "master" ]
workflow_dispatch:

# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
group: "gh-pages"
cancel-in-progress: false

permissions: {}

jobs:
build:
name: Build site
runs-on: ubuntu-latest
if: github.repository_owner == 'silverstripe'
permissions:
contents: read
steps:
- name: Install PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.1

- name: Checkout code
uses: actions/checkout@v4

- name: Setup GH pages
id: pages
uses: actions/configure-pages@v5

- name: Build static files
shell: bash
run: |
composer install
./makedoc.sh
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: "htdocs/"

deploy:
name: Deploy site
needs: build
runs-on: ubuntu-latest
if: github.repository_owner == 'silverstripe'
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{steps.deployment.outputs.page_url}}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
1 change: 1 addition & 0 deletions conf/doctum.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"4": "4.x",
"3": "3.x"
},
"default_version": "5",
"paths": {
"www": "htdocs",
"cache": "data/cache",
Expand Down
5 changes: 3 additions & 2 deletions conf/doctum.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

use PhpParser\NodeTraverser;
use PhpParser\NodeVisitor\NameResolver;
use Doctum\Project;
use Doctum\Doctum;
use SilverStripe\ApiDocs\Data\ApiJsonStore;
use SilverStripe\ApiDocs\Data\Config;
use SilverStripe\ApiDocs\Inspections\RecipeFinder;
use SilverStripe\ApiDocs\Inspections\RecipeVersionCollection;
use SilverStripe\ApiDocs\RemoteRepository\SilverStripeRemoteRepository;
use SilverStripe\ApiDocs\SilverstripeProject;

// Get config
$config = Config::getConfig();
Expand Down Expand Up @@ -70,7 +70,7 @@
// Override project
unset($doctum['project']);
$doctum['project'] = function ($sc) {
$project = new Project($sc['store'], $sc['_versions'], array(
$project = new SilverstripeProject($sc['store'], $sc['_versions'], array(
'build_dir' => $sc['build_dir'],
'cache_dir' => $sc['cache_dir'],
'remote_repository' => $sc['remote_repository'],
Expand All @@ -82,6 +82,7 @@
'source_dir' => $sc['source_dir'],
'insert_todos' => $sc['insert_todos'],
'base_url' => $sc['base_url'],
'favicon' => 'favicon.ico',
'footer_link' => [
'href' => 'https://github.com/silverstripe/api.silverstripe.org',
'rel' => 'noreferrer noopener',
Expand Down
40 changes: 40 additions & 0 deletions conf/themes/silverstripe/404.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<!doctype html>
<html lang="en-NZ">
<head>
{# NOTE: Do not put this file into the manifest.yml, as that would render it per version rather than in the base dir #}
<title>Not Found | {{ project.config('title') }}</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
{% if project.config('favicon') %}
<link rel="shortcut icon" href="{{ project.config('favicon') }}" />
{%- endif %}
<link rel="stylesheet" type="text/css" href="/css/error-styles.css">
<script>
const allowedVersions = {{ versions|json_encode|raw }};
// If the 404 looks like it could be for a class, redirect to the search page.
// Use the current version if it's valid, otherwise use the default.
const path = window.location.pathname;
let version = path.replace('^\/?(\d+)\/', '$1');
if (!version.match(/^\d$/) || !allowedVersions.includes(version)) {
version = '{{ default_version }}'
}
const possibleClass = path.replace(/^\/?\d+\/(.*)\.html/, '$1').replaceAll('/', '\\');
// Class name regex from https://www.php.net/manual/en/language.oop5.basic.php and modified to account for namespaces
if (possibleClass.match(/^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*(\\[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*)*$/)) {
const url = `/${version}/search.html/?search=${encodeURIComponent(possibleClass)}`;
console.log(`Redirecting to ${url}`);
window.location.assign(url);
}
</script>
</head>
<body>
<div class="gif_holder">
<div class="color_overlay">
<div class="text_container">
<h2>Whoa 404, either we broke something or you had a typing mishap :-/</h2>
<h3> Let's go back <a href="/{{ default_version }}">home.</a></h3>
</div>
</div>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.gif_holder {
background-image: url('https://www.silverstripe.com/themes/ssv3/img/banners/page-not-found.gif');
background-image: url('/images/page-not-found.gif');
position: relative;
z-index: 807;
-webkit-background-size: cover;
Expand Down Expand Up @@ -52,5 +52,5 @@ a:hover {

body {
padding: 0;
margin: 0;"
}
margin: 0;
}
Binary file added conf/themes/silverstripe/images/favicon.ico
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions conf/themes/silverstripe/main_index.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
{# NOTE: Do not put this file into the manifest.yml, as that would render it per version rather than as the main index file #}
<title>Redirecting...</title>
<link rel="canonical" href="https://api.silverstripe.org/{{ default_version }}/index.html" />
<meta charset="UTF-8" />
<meta http-equiv="refresh" content="0;url={{ default_version }}/index.html" />
{% if project.config('favicon') %}
<link rel="shortcut icon" href="{{ project.config('favicon') }}" />
{%- endif %}
</head>
<body>
<p>Redirecting... if you aren't redirected automatically, <a href="{{ default_version }}/index.html">click here</a></p>
</body>
</html>
68 changes: 68 additions & 0 deletions conf/themes/silverstripe/main_search.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<!DOCTYPE html>
<html>
<head>
{# NOTE: Do not put this file into the manifest.yml, as that would render it per version rather than in the base dir #}
<title>Redirecting...</title>
<link rel="canonical" href="https://api.silverstripe.org/{{ default_version }}/search.html" />
<meta charset="UTF-8" />
{% if project.config('favicon') %}
<link rel="shortcut icon" href="{{ project.config('favicon') }}" />
{%- endif %}
<script>
function getRedirectUrl() {
const allowedVersions = {{ versions|json_encode|raw }};
const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString);
const query = urlParams.get('q');
// Get version - if a full version is passed, just get the major.
let version = urlParams.get('version') ?? '';
version = version.replace(/^(\d+)\..*$/, '$1');
if (!version.match(/^\d$/) || !allowedVersions.includes(version)) {
version = '{{ default_version }}';
}
// If there's no query, just go to the versioned search page
if (!query) {
return `/${version}/search.html`;
}
// Convert API link syntax to class and property/method references
const search = query.replaceAll('()', '').replaceAll('$', '');
const searchParts = search.split(/::|->/);
const searchConfig = {
class: null,
property: null,
type: null,
};
if (searchParts.length === 2) {
searchConfig.class = searchParts[0];
searchConfig.property = searchParts[1];
searchConfig.type = query.includes('()') ? 'method' : 'property';
} else {
searchConfig.class = search;
searchConfig.type = 'class';
}
// If we don't have a class, redirect to search
if (!searchConfig.class) {
return `/${version}/search.html`;
}
// Return the page for that class, with optional anchor link
// We can't check if the page actually exists here - but the 404 page will handle that
let searchPath = `/${version}/${searchConfig.class.replaceAll('\\', '/')}.html`;
if (searchConfig.property && searchConfig.type) {
searchPath += `#${searchConfig.type}_${searchConfig.property}`;
}
return searchPath;
}
const url = getRedirectUrl();
console.log(`Redirecting to ${url}`);
window.location.assign(url);
</script>
</head>
<body>
{# Fall back to just sending users to the default search page if the redirect fails for some reason #}
<p>Redirecting... if you aren't redirected automatically, <a href="{{ default_version }}/search.html">click here</a></p>
</body>
</html>
5 changes: 5 additions & 0 deletions conf/themes/silverstripe/manifest.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
name: silverstripe
parent: default

static:
'images/favicon.ico': 'favicon.ico'
'images/page-not-found.gif': 'images/page-not-found.gif'
'css/error-styles.css': 'css/error-styles.css'

global:
'doctum.js.twig': 'doctum.js'

Expand Down
24 changes: 0 additions & 24 deletions errors/404.html

This file was deleted.

47 changes: 47 additions & 0 deletions src/SilverstripeProject.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace SilverStripe\ApiDocs;

use Doctum\Project;
use SilverStripe\ApiDocs\Data\Config;

class SilverstripeProject extends Project
{
public function update($callback = null, $force = false): void
{
parent::update($callback, $force);
$this->renderMainPages();
}

public function render($callback = null, $force = false): void
{
parent::render($callback, $force);
$this->renderMainPages();
}

/**
* Renders pages that are not version dependent such as the main index.html
*/
private function renderMainPages()
{
$this->version = '';
$this->initialize();
$config = Config::getConfig();
$variables = [
// Get array of strings of major version numbers
'versions' => array_map(fn($version) => (string)$version, array_keys($config['versions'])),
'default_version' => $config['default_version'],
];
$this->renderer->save($this, 'index.html', 'main_index.twig', $variables);
$this->renderer->save($this, 'search.html', 'main_search.twig', $variables);
$this->renderer->save($this, '404.html', '404.twig', $variables);
}

protected function replaceVars(string $pattern): string
{
if (!$this->version) {
$pattern = str_replace('%version%/', '', $pattern);
}
return parent::replaceVars($pattern);
}
}

0 comments on commit 504e2fe

Please sign in to comment.