Skip to content

Commit

Permalink
Merge pull request #61 from asgrim/docs-publish
Browse files Browse the repository at this point in the history
Publish docs with GH Pages
  • Loading branch information
asgrim authored Oct 3, 2024
2 parents a1b521e + a7781b5 commit e0112de
Show file tree
Hide file tree
Showing 8 changed files with 272 additions and 1 deletion.
17 changes: 17 additions & 0 deletions .github/docs/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM ghcr.io/roave/docbooktool:1.16.0 AS builder

COPY ./.github/docs/templates /docs-src/templates
COPY ./docs /docs-src/book
COPY ./.github/docs/index-front-matter.yml /docs-src/book/index.md
RUN --mount=type=bind,source=./README.md,target=/tmp/index.md \
cat /tmp/index.md >> /docs-src/book/index.md
COPY ./features /docs-src/features

FROM builder AS built

RUN bin/docbook-tool --html
RUN rm -Rf /docs-package/pdf

FROM scratch AS output

COPY --from=built /docs-package /
8 changes: 8 additions & 0 deletions .github/docs/build-docs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash

set -xeuo pipefail

cd "$(dirname "$0")/../.."

rm -Rf docs-package
docker buildx build -f .github/docs/Dockerfile --target=output --output=docs-package .
4 changes: 4 additions & 0 deletions .github/docs/index-front-matter.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
title: Home
order: 1
---
188 changes: 188 additions & 0 deletions .github/docs/templates/online.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>PIE Documentation</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<style>
.selected {
background-color: #7A86B8;
}
.selected a, .selected a:focus {
color: white;
}
.hidden {
display: none;
}
</style>
</head>
<body>
<ul id="top-nav-tabs" class="invisible"><li><a href="#docs" class="fragmentRoute">Documentation</a></li></ul>
<div class="container">
<header class="d-flex flex-wrap justify-content-center py-3 mb-4 border-bottom">
<a href="#docs" class="d-flex align-items-center mb-3 mb-md-0 me-md-auto link-body-emphasis text-decoration-none">
<svg class="bi me-2" width="40" height="32"><use xlink:href="#bootstrap"/></svg>
<span class="fs-4">🥧 <strong>P</strong>HP <strong>I</strong>nstaller for <strong>E</strong>xtensions</span>
</a>

<ul class="nav nav-pills" id="docs-side-nav">
{% for page in pages %}
<li class="nav-item"><a href="#docs/{{ page.slug }}" class="nav-link fragmentRoute">{{ page.title }}</a></li>
{% endfor %}
</ul>
</header>
</div>

<section id="docs" class="tab-content"><div id="docs-content">
{% for page in pages %}
<section id="docs/{{ page.slug }}" class="container my-md-4 bd-layout hidden">
{{ page.content|preg_replace('~\./docs/~', '')|raw }}
</section>
{% endfor %}
</div></section>

<script>
/**
* @param {string} title
*/
function loadDocBookNavigation(title) {
/**
* @param {NodeListOf<HTMLElement>} unselectedListElements
* @param {HTMLElement} selectedListElement
* @param {boolean} applySelectedClass
* @param {boolean} applyHiddenClass
*/
function selectFromList(unselectedListElements, selectedListElement, applySelectedClass, applyHiddenClass)
{
for (let i = 0; i < unselectedListElements.length; i++) {
if (applySelectedClass && unselectedListElements[i].classList.contains('selected')) {
unselectedListElements[i].classList.remove('selected');
}
if (applyHiddenClass && ! unselectedListElements[i].classList.contains('hidden')) {
unselectedListElements[i].classList.add('hidden');
}
}
if (applySelectedClass) {
selectedListElement.classList.add('selected');
}
if (applyHiddenClass) {
selectedListElement.classList.remove('hidden');
}
}
function fragmentRoute(pathWithHash, pageTitle) {
const path = pathWithHash.substring(1);
const pathParts = path.split("/");
if (pathParts.length >= 1) {
const topTabLink = document.querySelector('#top-nav-tabs a[href="#' + pathParts[0] + '"]');
if (topTabLink.parentElement) {
selectFromList(document.querySelectorAll('ul#top-nav-tabs li'), topTabLink.parentElement, true, false);
}
selectFromList(document.querySelectorAll('section.tab-content'), document.getElementById(pathParts[0]), false, true);
pageTitle = topTabLink.innerHTML + ' :: ' + pageTitle;
}
if (pathParts.length >= 2) {
const docsSectionLink = document.querySelector('#docs-side-nav a[href="#docs/' + pathParts[1] + '"]');
selectFromList(document.querySelectorAll('ul#docs-side-nav li'), docsSectionLink.parentElement, true, false);
selectFromList(document.querySelectorAll('div#docs-content section'), document.getElementById('docs/' + pathParts[1]), false, true);
pageTitle = docsSectionLink.innerHTML + ' :: ' + pageTitle;
document.getElementById('docs-content').scrollTo(0, 0);
}
if (pathParts.length >= 3) {
document.querySelectorAll('.selectedHeaderFromRoute').forEach(function (element) {
element.classList.remove('selectedHeaderFromRoute');
});
const selectedHeader = document.querySelector('[id="' + path + '"]');
selectedHeader.scrollIntoView();
selectedHeader.classList.add('selectedHeaderFromRoute');
}
document.title = pageTitle;
window.history.pushState(
{},
pageTitle,
/([^#]+)#?.*/.exec(window.location.href)[1] + pathWithHash
);
}
document.querySelectorAll('.fragmentRoute').forEach(function (e) {
e.addEventListener('click',
/**
* @param {MouseEvent} clickEvent
*/
function (clickEvent) {
/** @type {EventTarget & HTMLAnchorElement} */
const target = clickEvent.target;
fragmentRoute(target.getAttribute('href'), title);
clickEvent.stopPropagation();
clickEvent.preventDefault();
}
);
});
// This JS is meant to be run in a single page context where navigation links to pages are actually
// page jumps within a single HTML page.
document.querySelectorAll('a:not(.fragmentRoute)').forEach(function (e) {
e.addEventListener('click',
/**
* @param {MouseEvent} clickEvent
*/
function (clickEvent) {
let href = clickEvent.target.getAttribute('href');
// If a protocol is set OR the URL is set to use whichever protocol is appropriate i.e. `//foo.com`
let looksLikeAbsolutePath = (href) => href.indexOf('://') > 0 || href.indexOf('//') === 0;
if (looksLikeAbsolutePath(href)) {
return;
}
// Right now this is assuming that documentation pages are written in Markdown
let pageJump = `#docs/${href.replace('/', '_').replace('.md', '')}`;
fragmentRoute(pageJump, title);
clickEvent.stopPropagation();
clickEvent.preventDefault();
}
);
});
document.querySelectorAll('h1[id],h2[id],h3[id],h4[id],h5[id],h6[id]').forEach(function (e) {
let a = document.createElement('A');
a.classList.add('permalink');
a.href = '#' + e.id;
a.innerHTML = '<i class="fas fa-link"></i>';
a.title = 'Right click and copy to make a link to this section';
a.addEventListener('click',
/**
* @param {MouseEvent} clickEvent
*/
function (clickEvent) {
/** @type {EventTarget & HTMLAnchorElement} */
const target = clickEvent.target.parentElement;
fragmentRoute(target.getAttribute('href'), title);
clickEvent.stopPropagation();
clickEvent.preventDefault();
}
);
e.appendChild(a);
});
// // If we have a valid fragment in URL, select the appropriate tab, default to general docs
setTimeout(() => {
if (window.location.hash) {
fragmentRoute(window.location.hash, title);
} else {
fragmentRoute('#docs/index', title);
}
}, 100);
}
loadDocBookNavigation("PIE Documentation");
</script>
</body>
</html>
45 changes: 45 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
on:
# Runs on pushes targeting the default branch
push:
branches: ["main"]

# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write

# 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: "pages"
cancel-in-progress: false

jobs:
# Build job
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build documentation
run: .github/docs/build-docs.sh
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: docs-package

# Deployment job
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ behat.yml
box.json
box.phar
pie.phar
/docs-package/
4 changes: 4 additions & 0 deletions docs/extension-maintainers.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
---
title: Extension Maintainers
order: 3
---
# PIE for Extension Maintainers

Adding PIE support for your extension is relatively straightforward, and the
Expand Down
6 changes: 5 additions & 1 deletion docs/usage.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# PIE Usage for Extension Maintainers
---
title: Using PIE
order: 2
---
# PIE Usage

## Installing PIE

Expand Down

0 comments on commit e0112de

Please sign in to comment.