Public Access
A search page whose index is the page itself: one item for each page and each heading of the guide, the how-tos, the FAQ and the developer docs, written by Zola from the pages' own content. A small script filters and ranks them as you type. Nothing is fetched, so the Content-Security-Policy needs nothing new; without JavaScript the page is a list of every heading. The navigation gets a link, and the documentation's index pages a box that is a plain form to /search/?q=. The devlog is not searched. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
This commit is contained in:
@@ -33,6 +33,7 @@
|
||||
<a href="/dev/">Developers</a>
|
||||
<a href="/downloads/">Downloads</a>
|
||||
<a href="/devlog/">Devlog</a>
|
||||
<a href="/search/">Search</a>
|
||||
<button class="link-btn js-only" id="theme-toggle" type="button">Light</button>
|
||||
<a class="btn btn-primary n-md" href="{{ config.extra.repo }}">Source</a>
|
||||
</nav>
|
||||
|
||||
@@ -11,6 +11,12 @@
|
||||
|
||||
<div class="prose">{{ section.content | safe }}</div>
|
||||
|
||||
<form class="search-form search-mini" action="/search/" method="get" role="search">
|
||||
<label class="sr" for="q">Search the documentation</label>
|
||||
<input id="q" name="q" type="search" autocomplete="off" spellcheck="false" placeholder="Search the documentation">
|
||||
<button class="btn n-md" type="submit">Search</button>
|
||||
</form>
|
||||
|
||||
<div class="cards">
|
||||
{% for path in section.subsections %}
|
||||
{% set sub = get_section(path=path) %}
|
||||
|
||||
@@ -11,6 +11,12 @@
|
||||
|
||||
<div class="prose">{{ section.content | safe }}</div>
|
||||
|
||||
<form class="search-form search-mini" action="/search/" method="get" role="search">
|
||||
<label class="sr" for="q">Search the documentation</label>
|
||||
<input id="q" name="q" type="search" autocomplete="off" spellcheck="false" placeholder="Search the documentation">
|
||||
<button class="btn n-md" type="submit">Search</button>
|
||||
</form>
|
||||
|
||||
<div class="cards">
|
||||
{% for p in section.pages %}
|
||||
<article class="card n-lg">
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
{# One entry of the search page for each part of a page: what comes before its first heading,
|
||||
then each "## heading" with what follows it. The text is the page's own, tags taken out. #}
|
||||
{% macro entries(page, group) %}
|
||||
{% set parts = page.content | split(pat='<h2 id="') %}
|
||||
{% for part in parts %}
|
||||
{% if loop.first %}
|
||||
<li class="s-entry" data-group="{{ group }}"><a href="{{ page.path | safe }}">{{ page.title }}</a><span class="s-where">{{ group }}</span><p class="s-text">{{ page.description }} {{ part | striptags | trim | safe }}</p></li>
|
||||
{% else %}
|
||||
{% set anchor = part | split(pat='"') | first %}
|
||||
{% set head = part | split(pat="</h2>") | first %}
|
||||
{% set heading = head | split(pat='">') | slice(start=1) | join(sep='">') | striptags | trim %}
|
||||
{% set body = part | split(pat="</h2>") | slice(start=1) | join(sep="</h2>") | striptags | trim %}
|
||||
<li class="s-entry s-part" data-group="{{ group }}"><a href="{{ page.path | safe }}#{{ anchor }}">{{ heading | safe }}</a><span class="s-where">{{ group }} · {{ page.title }}</span><p class="s-text">{{ body | safe }}</p></li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endmacro entries %}
|
||||
@@ -0,0 +1,46 @@
|
||||
{% extends "base.html" %}
|
||||
{% import "macros/search.html" as search %}
|
||||
{% block title %}{{ page.title }}: roro9stack{% endblock %}
|
||||
{% block description %}{{ page.description }}{% endblock %}
|
||||
{% block head %}<script src="/js/search.js" defer></script>{% endblock %}
|
||||
{% block main %}
|
||||
{# The whole index is in this page (issue #60): nothing is fetched, and without JavaScript it is
|
||||
still a list of every page and heading of the documentation. js/search.js filters it. #}
|
||||
<div class="wrap page">
|
||||
<header>
|
||||
<span class="eyebrow">Documentation</span>
|
||||
<h1>{{ page.title }}</h1>
|
||||
<p class="lead">{{ page.description }}</p>
|
||||
</header>
|
||||
|
||||
<form class="search-form" action="/search/" method="get" role="search">
|
||||
<label for="q">Search the guide, the how-tos, the FAQ and the developer docs</label>
|
||||
<input id="q" name="q" type="search" autocomplete="off" spellcheck="false" placeholder="Probation, Safe Mode, rm -r, ...">
|
||||
<button class="btn btn-primary n-md" type="submit">Search</button>
|
||||
</form>
|
||||
<p class="s-status muted" id="s-status" role="status" aria-live="polite"></p>
|
||||
<ol class="s-results" id="s-results" hidden></ol>
|
||||
|
||||
<div class="s-index" id="s-index">
|
||||
<p class="muted s-nojs">Every page of the documentation and its headings. With JavaScript on, the box above searches their text.</p>
|
||||
{% set guide = get_section(path="guide/_index.md") %}
|
||||
<section><h2>{{ guide.title }}</h2><ul>
|
||||
{% for p in guide.pages %}{{ search::entries(page=p, group="Guide") }}{% endfor %}
|
||||
</ul></section>
|
||||
{% set howto = get_section(path="howto/_index.md") %}
|
||||
<section><h2>{{ howto.title }}</h2><ul>
|
||||
{% for p in howto.pages %}{{ search::entries(page=p, group="How-to") }}{% endfor %}
|
||||
</ul></section>
|
||||
<section><h2>Questions and answers</h2><ul>
|
||||
{{ search::entries(page=get_page(path="faq.md"), group="FAQ") }}
|
||||
</ul></section>
|
||||
{% set dev = get_section(path="dev/_index.md") %}
|
||||
{% for path in dev.subsections %}
|
||||
{% set sub = get_section(path=path) %}
|
||||
<section><h2>Developers: {{ sub.title }}</h2><ul>
|
||||
{% for p in sub.pages %}{{ search::entries(page=p, group=sub.extra.search | default(value=sub.title)) }}{% endfor %}
|
||||
</ul></section>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock main %}
|
||||
Reference in New Issue
Block a user