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
12 changes: 0 additions & 12 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,18 +236,6 @@ Tabbed content blocks for alternative instructions.
- Keyboard accessible
- Code blocks and prose supported inside tabs

### Page Tags

Categorize pages with tags for improved discoverability.

- Add tags via frontmatter (`tags: [Python, Testing, API]`)
- Auto-generated tags index page listing all tags and linked pages
- Tags rendered above page title with links to tag index
- Nested/hierarchical tags (e.g., `Python/Testing`)
- Shadow tags for internal organization (hidden from public view)
- Scoped tag listings per documentation section
- Optional tag icons

### Enhanced Search

Improve the built-in search with modern capabilities.
Expand Down
2 changes: 2 additions & 0 deletions great-docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ nav_icons:
Link Checker: scan-search
Proofreading: spell-check
Changelog: history
Custom Static Pages: app-window
Page Tags: tags
Community Files: file-heart
Docs Linting: list-checks

Expand Down
163 changes: 163 additions & 0 deletions great_docs/_translations.py
Original file line number Diff line number Diff line change
Expand Up @@ -4443,6 +4443,169 @@
"ar": "صدر بتاريخ {date}",
"he": "שוחרר ב-{date}",
},
# ── Page Tags ─────────────────────────────────────────────────────────
"tags_title": {
"en": "Tags",
"fr": "Étiquettes",
"de": "Schlagwörter",
"es": "Etiquetas",
"pt": "Etiquetas",
"it": "Etichette",
"nl": "Tags",
"ja": "タグ",
"ko": "태그",
"zh-Hans": "标签",
"zh-Hant": "標籤",
"ru": "Теги",
"pl": "Tagi",
"tr": "Etiketler",
"sv": "Taggar",
"da": "Tags",
"nb": "Tagger",
"is": "Merki",
"fi": "Tunnisteet",
"cs": "Štítky",
"ro": "Etichete",
"el": "Ετικέτες",
"hi": "टैग",
"ar": "علامات",
"he": "תגיות",
},
"tags_nav": {
"en": "Tags",
"fr": "Étiquettes",
"de": "Schlagwörter",
"es": "Etiquetas",
"pt": "Etiquetas",
"it": "Etichette",
"nl": "Tags",
"ja": "タグ",
"ko": "태그",
"zh-Hans": "标签",
"zh-Hant": "標籤",
"ru": "Теги",
"pl": "Tagi",
"tr": "Etiketler",
"sv": "Taggar",
"da": "Tags",
"nb": "Tagger",
"is": "Merki",
"fi": "Tunnisteet",
"cs": "Štítky",
"ro": "Etichete",
"el": "Ετικέτες",
"hi": "टैग",
"ar": "علامات",
"he": "תגיות",
},
"tags_page_count_one": {
"en": "1 page in {sections}",
"fr": "1 page dans {sections}",
"de": "1 Seite in {sections}",
"es": "1 página en {sections}",
"pt": "1 página em {sections}",
"it": "1 pagina in {sections}",
"nl": "1 pagina in {sections}",
"ja": "{sections}に1ページ",
"ko": "{sections}에 1페이지",
"zh-Hans": "{sections}中1个页面",
"zh-Hant": "{sections}中1個頁面",
"ru": "1 страница в {sections}",
"pl": "1 strona w {sections}",
"tr": "{sections} içinde 1 sayfa",
"sv": "1 sida i {sections}",
"da": "1 side i {sections}",
"nb": "1 side i {sections}",
"is": "1 síða í {sections}",
"fi": "1 sivu osiossa {sections}",
"cs": "1 stránka v {sections}",
"ro": "1 pagină în {sections}",
"el": "1 σελίδα στο {sections}",
"hi": "{sections} में 1 पृष्ठ",
"ar": "صفحة واحدة في {sections}",
"he": "עמוד אחד ב-{sections}",
},
"tags_page_count_other": {
"en": "{count} pages in {sections}",
"fr": "{count} pages dans {sections}",
"de": "{count} Seiten in {sections}",
"es": "{count} páginas en {sections}",
"pt": "{count} páginas em {sections}",
"it": "{count} pagine in {sections}",
"nl": "{count} pagina's in {sections}",
"ja": "{sections}に{count}ページ",
"ko": "{sections}에 {count}페이지",
"zh-Hans": "{sections}中{count}个页面",
"zh-Hant": "{sections}中{count}個頁面",
"ru": "{count} страниц в {sections}",
"pl": "{count} stron w {sections}",
"tr": "{sections} içinde {count} sayfa",
"sv": "{count} sidor i {sections}",
"da": "{count} sider i {sections}",
"nb": "{count} sider i {sections}",
"is": "{count} síður í {sections}",
"fi": "{count} sivua osiossa {sections}",
"cs": "{count} stránek v {sections}",
"ro": "{count} pagini în {sections}",
"el": "{count} σελίδες στο {sections}",
"hi": "{sections} में {count} पृष्ठ",
"ar": "{count} صفحات في {sections}",
"he": "{count} עמודים ב-{sections}",
},
"tags_page_count_one_no_section": {
"en": "1 page",
"fr": "1 page",
"de": "1 Seite",
"es": "1 página",
"pt": "1 página",
"it": "1 pagina",
"nl": "1 pagina",
"ja": "1ページ",
"ko": "1페이지",
"zh-Hans": "1个页面",
"zh-Hant": "1個頁面",
"ru": "1 страница",
"pl": "1 strona",
"tr": "1 sayfa",
"sv": "1 sida",
"da": "1 side",
"nb": "1 side",
"is": "1 síða",
"fi": "1 sivu",
"cs": "1 stránka",
"ro": "1 pagină",
"el": "1 σελίδα",
"hi": "1 पृष्ठ",
"ar": "صفحة واحدة",
"he": "עמוד אחד",
},
"tags_page_count_other_no_section": {
"en": "{count} pages",
"fr": "{count} pages",
"de": "{count} Seiten",
"es": "{count} páginas",
"pt": "{count} páginas",
"it": "{count} pagine",
"nl": "{count} pagina's",
"ja": "{count}ページ",
"ko": "{count}페이지",
"zh-Hans": "{count}个页面",
"zh-Hant": "{count}個頁面",
"ru": "{count} страниц",
"pl": "{count} stron",
"tr": "{count} sayfa",
"sv": "{count} sidor",
"da": "{count} sider",
"nb": "{count} sider",
"is": "{count} síður",
"fi": "{count} sivua",
"cs": "{count} stránek",
"ro": "{count} pagini",
"el": "{count} σελίδες",
"hi": "{count} पृष्ठ",
"ar": "{count} صفحات",
"he": "{count} עמודים",
},
}


Expand Down
3 changes: 3 additions & 0 deletions great_docs/assets/copy-page.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@
// Skip the License page (has its own layout)
if (document.body.classList.contains('gd-license-page')) return;

// Skip the Tags index page
if (document.body.classList.contains('gd-tags-index')) return;

// Create the widget container
var widget = document.createElement('div');
widget.className = 'gd-copy-page';
Expand Down
163 changes: 163 additions & 0 deletions great_docs/assets/great-docs.scss
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ header p {

.description {
font-style: italic;

@media (max-width: 767.98px) {
padding-bottom: 1em;
}
}

table {
Expand Down Expand Up @@ -5525,6 +5529,165 @@ html[data-bs-theme="dark"] {
/* Dark mode — icon color inherits from text (stroke: currentColor) */
/* No extra rules needed because Lucide uses stroke="currentColor" */

// ── Page Tags ───────────────────────────────────────────────────────────────

// Tag pills displayed below page titles
.gd-page-tags {
display: flex;
flex-wrap: wrap;
gap: 0.4rem;
margin-top: 0.35rem;
margin-bottom: 0.8rem;
}

.gd-tag-pill {
display: inline-flex;
align-items: center;
gap: 0.2rem;
padding: 0.15rem 0.55rem;
font-size: 0.75rem;
font-weight: 500;
line-height: 1.4;
color: mix($primary, $body-color, 60%);
background-color: tint-color($primary, 90%);
border: 1px solid tint-color($primary, 75%);
border-radius: 1rem;
text-decoration: none;
transition: background-color 0.15s ease, border-color 0.15s ease;
white-space: nowrap;

&:hover,
&:focus-visible {
background-color: tint-color($primary, 80%);
border-color: tint-color($primary, 60%);
color: shade-color($primary, 10%);
text-decoration: none;
}

.gd-tag-icon {
display: inline-flex;
align-items: center;
margin-right: 0.15rem;
opacity: 0.7;
}
}

// Tags index page — headings styled as pills
.gd-tag-heading {
margin-top: 1.5rem;
margin-bottom: 0.35rem;

.gd-tag-pill {
cursor: default;
pointer-events: none;
}
}

// Indentation for subtags (depth 1 = child, depth 2 = grandchild)
.gd-tag-indent-1 {
margin-left: 2rem;
}

.gd-tag-indent-2 {
margin-left: 4rem;
}

// Page links under each tag (no bullets, indented)
.gd-tag-pages {
margin-bottom: 0.75rem;
}

.gd-tag-page-link {
padding: 0.15rem 0;
padding-left: 1.25rem;

a {
color: $body-color;
text-decoration: underline;

&:hover {
color: $primary;
}
}
}

// Segmented pills for hierarchical tags (e.g. Python | Advanced)
.gd-tag-pill-segmented {
padding: 0;
overflow: hidden;
gap: 0;

.gd-tag-pill-segment {
display: inline-flex;
align-items: center;
padding: 0.15rem 0.55rem;
}

.gd-tag-pill-parent {
background-color: tint-color($primary, 90%);
}

.gd-tag-pill-segment:not(.gd-tag-pill-parent) {
background-color: tint-color($primary, 95%);
}

.gd-tag-pill-sep {
display: inline-block;
width: 1px;
align-self: stretch;
background-color: tint-color($primary, 60%);
}
}

.gd-tag-section {
display: inline-block;
font-size: 0.7rem;
font-weight: 500;
color: $text-muted;
background-color: $gray-100;
padding: 0.05rem 0.4rem;
border-radius: 0.25rem;
margin-left: 0.4rem;
vertical-align: middle;
}

// Dark mode overrides for tag pills
body.quarto-dark {
.gd-tag-pill {
color: tint-color($primary, 70%);
background-color: rgba($primary, 0.15);
border-color: rgba($primary, 0.3);

&:hover,
&:focus-visible {
background-color: rgba($primary, 0.25);
border-color: rgba($primary, 0.5);
color: tint-color($primary, 85%);
}
}

.gd-tag-section {
color: $gray-400;
background-color: $gray-800;
}

.gd-tag-pill-sep {
background-color: rgba($primary, 0.4);
}

.gd-tag-pill-segmented .gd-tag-pill-parent {
background-color: rgba($primary, 0.15);
}

.gd-tag-pill-segmented .gd-tag-pill-segment:not(.gd-tag-pill-parent) {
background-color: rgba($primary, 0.08);
}

.gd-tag-page-link a {
color: $gray-300;
}
}


/*-- scss:functions --*/

Expand Down
Loading
Loading