Grammar Page Organization Dropdown

Specification for adding an "arrange by" selector to /grammar with four orderings: category (current), JLPT level, textbook chapter, and a site-recommended reading order. Written 2026-07-25 against the working tree on main. No page changes are made by this document.

1. How the page works today

The grammar index (grammar.md) is pure Liquid. It collects every published explanation page — currently 98 files with layout: explanation under _grammar/ — and groups them by a section value. That value is not written in front matter: the folder_categorizer.rb plugin derives section and subsection from the folder path (_grammar/Necessity/〜べき/… → section "Necessity"). Sections render alphabetically, and within each section the grammar-subsection.md include emits a flat link list sorted by japanese, then title.

Two facts shape this spec:

2. Recommended architecture: pre-render all views, toggle with JS

Render all four organizations into /grammar at build time, each inside its own container. Exactly one container is visible; a dropdown at the top of the page switches between them. This is the simplest option that keeps the page working without JavaScript and requires no client-side templating.

Page structure

<div class="grammar-arrange">
  <label for="grammar-arrange-select">Arrange by</label>
  <select id="grammar-arrange-select">
    <option value="category">Category</option>
    <option value="recommended">Recommended reading order</option>
    <option value="jlpt">JLPT level</option>
    <option value="genki">Genki chapter</option>
  </select>
</div>

<div data-arrangement="category">    …current output, unchanged… </div>
<div data-arrangement="recommended" hidden> … </div>
<div data-arrangement="jlpt" hidden> … </div>
<div data-arrangement="genki" hidden> … </div>

New script: js/grammar-arrangement.js

Why not the alternatives

AlternativeWhy not
Four separate pages (/grammar/by-jlpt etc.)Splits inbound links and search results across four URLs, quadruples near-duplicate content for crawlers, and a "preference" can't persist across them without redirects.
One list re-sorted by JavaScriptThe four views aren't re-sorts of one flat list — each has different groupings (sections vs. levels vs. chapters vs. stages) with different headings and annotations. Client-side regrouping means shipping a JSON blob plus a templating layer; the Liquid build already does this for free.
Rendering only the selected view at build timeNot possible — static builds can't respond to a per-visitor choice.

Cost check: 98 links × 4 views is roughly 400 list items, well under anything that affects page weight or the ~2.2s serve loop. Duplicated links inside hidden containers are ignored by Pagefind's default indexing of visible text and are harmless for SEO as long as the default (category) view is the one visible without JS.

3. Data model: where each ordering's data lives

The four orderings need three kinds of data, and they should not all live in the same place. The dividing line: facts about a grammar pattern belong in that page's front matter; facts about a curriculum belong in a central data file.

ViewData neededWhere it livesNew work required
Categorysection / subsectionAlready derived from folder pathsNone
JLPTOne level per pageFront matter: jlpt: N4Tag all 98 pages
TextbookChapter number per page, per bookFront matter: genki: 12 (one flat key per textbook)Map pages to chapters; many pages will map to nothing
RecommendedAn ordered curriculumCentral file: _data/grammar_order.yamlAuthor the curriculum

3.1 JLPT: jlpt: N4 in front matter

---
layout: explanation
title: Should be with 〜べきだ
japanese: 〜べきだ
jlpt: N3
---

3.2 Textbooks: one flat front-matter key per book

---
japanese: 〜てもいい
jlpt: N5
genki: 6            # Genki I, Lesson 6
genki-note: Introduced as 〜てもいいですか
---

3.3 Recommended order: a central curriculum file, not per-page numbers

A per-page order: 37 key would be a maintenance trap: inserting one new page mid-sequence means renumbering dozens of files, and the curriculum as a whole would be invisible — readable only by grepping every file. Instead, define the order in one file that reads top-to-bottom as the curriculum itself:

# _data/grammar_order.yaml
- stage: The sentence skeleton
  blurb: >-
    Enough structure to tell who is doing what to whom in a
    speech bubble.
  pages:
    - /grammar/marking-the-subject-with-が
    - /grammar/marking-the-topic-with-は-and-も
    - /grammar/marking-the-direct-object-with-を
    # …

- stage: Verb endings you meet on page one
  blurb: >-
    Past, negative, and て-form — the inflections that appear in
    nearly every panel.
  pages:
    - /grammar/…

3.4 Rendering the curriculum in Liquid

For each permalink in the data file, find the matching document: site.grammar | where: "permalink", slug | first. That's an O(stages × pages × 98) scan — a few thousand comparisons, negligible against the current build. If it ever shows up in profiling, extend build_indexes.rb to expose a permalink→doc hash, but don't build that up front.

Validation: a typo'd permalink in the data file would silently drop a page. Add a small check — either in the existing plugin chain or as a _scripts/ lint run by hand — that warns when (a) a permalink in grammar_order.yaml matches no published page, or (b) a published page appears in no stage and is also absent from the intended-reference list. The same script can report JLPT/Genki tagging coverage while it's there.

4. Template changes

  1. grammar.md — becomes four blocks. The category block is the current loop, unchanged. New blocks: JLPT (group_by with fixed level order + "Beyond the JLPT" tail), Genki (numeric group_by + "Not covered" tail), recommended (loop over site.data.grammar_order + reference tail). The page is getting long enough that each view belongs in its own include (grammar-by-jlpt.md, etc.) with grammar.md reduced to the dropdown markup and four include calls.
  2. grammar-subsection.md — reusable as-is for the flat link lists inside every grouping; no changes needed.
  3. js/grammar-arrangement.js — new, per §2.
  4. CSS — a small _sass addition styling the dropdown row consistently with the theme selector.
  5. Optional, worth doing once data exists: the explanation layout can render the same metadata on each grammar page itself — a small line like JLPT N3 Genki L14 near the title. The data is per-page front matter precisely so this becomes free.

Accessibility and no-JS behavior

5. Open questions to settle before building

QuestionRecommendation
Which JLPT reference to follow when sources disagree?Pick one (Bunpro's list is the most complete) and note it once on the page; consistency matters more than the choice.
Genki 2nd or 3rd edition chapter numbers?3rd edition; lesson boundaries barely moved, and it's what current learners own.
Default view for first-time visitors?Category for now (matches inbound links and expectations). Revisit once the recommended order exists — it arguably serves a new visitor better, and the default is a one-line change.
Show JLPT pills in every view's lists?No — keep lists clean; the pill belongs on the explanation page itself.
Should dropdown options appear before their data is complete?No. Ship each option only when its view renders something respectable (see phasing below). A "JLPT" view where half the pages sit in a fallback bucket undermines trust.

6. Suggested phasing

  1. Infrastructure + recommended order. Dropdown, script, includes, and _data/grammar_order.yaml. This phase touches no grammar pages at all (the curriculum file is central), yet delivers the option with the most unique value — no other site can offer a manga-reading order over this exact content. Ship with two options: Category, Recommended.
  2. JLPT tagging. Add jlpt: to the 98 pages (mechanical; a script can propose levels from a reference list for human review). Enable the JLPT option and, optionally, the pill on explanation pages.
  3. Genki mapping. Add genki: where applicable, enable the Genki option with its "Not covered in Genki" tail. Later textbooks repeat this phase.
  4. Ongoing: the coverage lint from §3.4 keeps new pages from silently missing tags or curriculum slots; a line in the page-creation workflow (or the create-page skill) should prompt for jlpt: on every new grammar page.
Bottom line. One page, four pre-rendered views, one small script following the existing layout-switcher pattern. Per-page front matter for facts about patterns (jlpt:, genki:); one central YAML file for the curriculum. The recommended-order view is both the cheapest to ship (zero page edits) and the truest to the site's manga-reading mission — build it first.