mirror of
https://github.com/hugo-fixit/FixIt.git
synced 2026-09-03 04:02:40 +00:00
feat(assets): add table auto-numbering and sorting support
- Add CSS counter-based table auto-numbering with i18n support
- Add client-side table sorting with numeric/string/date detection
- Support per-table opt-out via Markdown attributes (number=false, sort=false)
- Add table caption support via {caption="..."} attribute
- Extract table styles from _content.scss to dedicated _table.scss
- Add TableConfig TypeScript interface
- Register table-sort script via .Store.hasTableSort for lazy loading
This commit is contained in:
@@ -12,6 +12,7 @@ tags:
|
||||
This post is a test post to preview the color syntax in Markdown.
|
||||
|
||||
<!--more-->
|
||||
<!-- markdownlint-disable MD055 MD056 -->
|
||||
|
||||
## 📝 Syntax
|
||||
|
||||
@@ -20,6 +21,7 @@ This post is a test post to preview the color syntax in Markdown.
|
||||
| HEX | `` `#RRGGBB` `` | `` `#0969DA` `` | `#0969DA` |
|
||||
| RGB | `` `rgb(R,G,B)` `` | `` `rgb(9, 105, 218)` `` | `rgb(9, 105, 218)` |
|
||||
| HSL | `` `hsl(H,S,L)` `` | `` `hsl(212, 92%, 45%)` `` | `hsl(212, 92%, 45%)` |
|
||||
{caption="Color syntax in Markdown"}
|
||||
|
||||
e.g. The background color is `#ffffff` for light mode and `#000000` for dark mode.
|
||||
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
/**
|
||||
* Table sort module for FixIt content blocks.
|
||||
*
|
||||
* Responsibilities:
|
||||
* - Initialize sortable tables (marked with `data-sortable` attribute).
|
||||
* - Add click handlers to `<th>` elements for ascending/descending/no-sort toggle.
|
||||
* - Support numeric, date, and string sorting.
|
||||
* - Re-initialize after content decryption events.
|
||||
*/
|
||||
import { eventBus } from '../core/event-bus'
|
||||
|
||||
type SortDirection = 'asc' | 'desc' | null
|
||||
|
||||
function detectValueType(value: string): 'number' | 'date' | 'string' {
|
||||
const stripped = value.replace(/[\s,%$€£¥]/g, '')
|
||||
if (stripped !== '' && !Number.isNaN(Number(stripped)))
|
||||
return 'number'
|
||||
if (/\d{4}[-/]\d{1,2}[-/]\d{1,2}/.test(value) && !Number.isNaN(Date.parse(value)))
|
||||
return 'date'
|
||||
return 'string'
|
||||
}
|
||||
|
||||
function compareValues(a: string, b: string, direction: SortDirection): number {
|
||||
if (!direction)
|
||||
return 0
|
||||
const type = detectValueType(a)
|
||||
let result = 0
|
||||
|
||||
switch (type) {
|
||||
case 'number':
|
||||
result = Number(a.replace(/[\s,%$€£¥]/g, '')) - Number(b.replace(/[\s,%$€£¥]/g, ''))
|
||||
break
|
||||
case 'date':
|
||||
result = new Date(a).getTime() - new Date(b).getTime()
|
||||
break
|
||||
default:
|
||||
result = a.localeCompare(b)
|
||||
}
|
||||
|
||||
return direction === 'asc' ? result : -result
|
||||
}
|
||||
|
||||
function nextDirection(current: SortDirection): SortDirection {
|
||||
if (current === null)
|
||||
return 'asc'
|
||||
if (current === 'asc')
|
||||
return 'desc'
|
||||
return null
|
||||
}
|
||||
|
||||
function sortTable(table: HTMLTableElement, colIndex: number, direction: SortDirection) {
|
||||
const tbody = table.querySelector('tbody')
|
||||
if (!tbody)
|
||||
return
|
||||
|
||||
const rows = Array.from(tbody.querySelectorAll('tr'))
|
||||
|
||||
if (!direction) {
|
||||
rows.sort((a, b) => {
|
||||
const orderA = parseInt(a.dataset.order || '0', 10)
|
||||
const orderB = parseInt(b.dataset.order || '0', 10)
|
||||
return orderA - orderB
|
||||
})
|
||||
}
|
||||
else {
|
||||
rows.sort((a, b) => {
|
||||
const cellA = a.children[colIndex]?.textContent?.trim() || ''
|
||||
const cellB = b.children[colIndex]?.textContent?.trim() || ''
|
||||
return compareValues(cellA, cellB, direction)
|
||||
})
|
||||
}
|
||||
|
||||
rows.forEach(row => tbody.appendChild(row))
|
||||
}
|
||||
|
||||
function updateSortIndicators(table: HTMLTableElement, colIndex: number, direction: SortDirection) {
|
||||
table.querySelectorAll('th').forEach((th, i) => {
|
||||
th.classList.remove('sort-asc', 'sort-desc')
|
||||
if (i === colIndex && direction) {
|
||||
th.classList.add(direction === 'asc' ? 'sort-asc' : 'sort-desc')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function initSortableTable(table: HTMLTableElement) {
|
||||
if (table.dataset.sortInit)
|
||||
return
|
||||
table.dataset.sortInit = 'true'
|
||||
|
||||
const tbody = table.querySelector('tbody')
|
||||
if (tbody) {
|
||||
Array.from(tbody.querySelectorAll('tr')).forEach((row, i) => {
|
||||
row.dataset.order = String(i)
|
||||
})
|
||||
}
|
||||
|
||||
table.classList.add('is-sortable')
|
||||
|
||||
const headers = table.querySelectorAll('thead th')
|
||||
headers.forEach((th, index) => {
|
||||
th.classList.add('sort-header')
|
||||
th.setAttribute('role', 'button')
|
||||
th.setAttribute('tabindex', '0')
|
||||
th.setAttribute('aria-sort', 'none')
|
||||
|
||||
const handleClick = () => {
|
||||
const currentDir = (table.dataset.sortDir === 'asc' && table.dataset.sortCol === String(index))
|
||||
? 'asc'
|
||||
: (table.dataset.sortDir === 'desc' && table.dataset.sortCol === String(index))
|
||||
? 'desc'
|
||||
: null
|
||||
|
||||
const newDir = nextDirection(currentDir)
|
||||
|
||||
if (newDir) {
|
||||
table.dataset.sortCol = String(index)
|
||||
table.dataset.sortDir = newDir
|
||||
th.setAttribute('aria-sort', newDir === 'asc' ? 'ascending' : 'descending')
|
||||
}
|
||||
else {
|
||||
delete table.dataset.sortCol
|
||||
delete table.dataset.sortDir
|
||||
th.setAttribute('aria-sort', 'none')
|
||||
}
|
||||
|
||||
sortTable(table, index, newDir)
|
||||
updateSortIndicators(table, index, newDir)
|
||||
}
|
||||
|
||||
th.addEventListener('click', handleClick, false)
|
||||
th.addEventListener('keydown', (e) => {
|
||||
if ((e as KeyboardEvent).key === 'Enter' || (e as KeyboardEvent).key === ' ') {
|
||||
e.preventDefault()
|
||||
handleClick()
|
||||
}
|
||||
}, false)
|
||||
})
|
||||
}
|
||||
|
||||
function initTableSort(target: Element | Document = document) {
|
||||
target.querySelectorAll<HTMLTableElement>('table[data-sortable]:not([data-sort-init])')
|
||||
.forEach(initSortableTable)
|
||||
}
|
||||
|
||||
function bindEvents() {
|
||||
eventBus.on('fixit:content-decrypted', ({ detail }) => {
|
||||
initTableSort(detail.target)
|
||||
})
|
||||
}
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
initTableSort()
|
||||
bindEvents()
|
||||
}, false)
|
||||
@@ -32,6 +32,7 @@ export interface FixItConfig {
|
||||
encryption?: EncryptionConfig
|
||||
print?: PrintConfig
|
||||
postChat?: boolean
|
||||
table?: TableConfig
|
||||
}
|
||||
|
||||
export interface EchartsConfig {
|
||||
@@ -121,3 +122,8 @@ export interface PrintConfig {
|
||||
expandDetails?: boolean
|
||||
expandFileTree?: boolean
|
||||
}
|
||||
|
||||
export interface TableConfig {
|
||||
number?: boolean
|
||||
sort?: boolean
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@
|
||||
|
||||
.content {
|
||||
margin-block: 1rem;
|
||||
counter-reset: h2 h3 h4 h5 h6;
|
||||
counter-reset: h2 h3 h4 h5 h6 table-counter;
|
||||
|
||||
> h2.heading-element {
|
||||
counter-increment: h2;
|
||||
@@ -167,6 +167,10 @@
|
||||
counter-increment: h6;
|
||||
}
|
||||
|
||||
> .table-wrapper table[data-table-numbered] {
|
||||
counter-increment: table-counter;
|
||||
}
|
||||
|
||||
> h2.heading-element .heading-numbered::before {
|
||||
content: counter(h2) ". ";
|
||||
}
|
||||
@@ -358,53 +362,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
.table-wrapper {
|
||||
position: relative;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
margin: 0.5rem 0;
|
||||
background: fi-var(table-background-color);
|
||||
border: 1px solid fi-var(table-border-color);
|
||||
@include border-radius;
|
||||
@include set-fi-var(scrollbar-thumb-color, fi-var(table-background-color));
|
||||
|
||||
> table {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
margin: 0;
|
||||
border-spacing: 0;
|
||||
background: fi-var(table-background-color);
|
||||
border-collapse: separate;
|
||||
|
||||
thead {
|
||||
background: fi-var(table-thead-color);
|
||||
}
|
||||
|
||||
&:not([class]) tbody {
|
||||
& tr:nth-child(odd) {
|
||||
background: light-dark(color.adjust($table-background-color, $lightness: -2.25%), color.adjust($table-background-color-dark, $lightness: 2.75%));
|
||||
}
|
||||
|
||||
& tr:hover {
|
||||
background: light-dark(color.adjust($table-background-color, $lightness: -4.5%), color.adjust($table-background-color-dark, $lightness: 5.5%));
|
||||
}
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
padding: 0.3rem 1rem;
|
||||
border-inline-end: 1px solid fi-var(table-border-color);
|
||||
border-bottom: 1px solid fi-var(table-border-color);
|
||||
}
|
||||
|
||||
tr > :last-child {
|
||||
border-inline-end: none;
|
||||
}
|
||||
|
||||
> :last-child > tr:last-child > * {
|
||||
border-bottom: none;
|
||||
}
|
||||
}
|
||||
> .table-wrapper table[data-table-numbered] {
|
||||
counter-increment: table-counter;
|
||||
}
|
||||
|
||||
img {
|
||||
|
||||
@@ -2,5 +2,6 @@
|
||||
@forward "shortcodes";
|
||||
@forward "alert";
|
||||
@forward "code";
|
||||
@forward "table";
|
||||
@forward "fixit-decryptor";
|
||||
@forward "patch";
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
@use "sass:color";
|
||||
@use "core/functions" as *;
|
||||
@use "core/mixins" as *;
|
||||
@use "variables" as *;
|
||||
|
||||
.table-wrapper {
|
||||
position: relative;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
margin: 0.5rem 0;
|
||||
background: fi-var(table-background-color);
|
||||
border: 1px solid fi-var(table-border-color);
|
||||
@include border-radius;
|
||||
@include set-fi-var(scrollbar-thumb-color, fi-var(table-background-color));
|
||||
|
||||
> table {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
margin: 0;
|
||||
border-spacing: 0;
|
||||
background: fi-var(table-background-color);
|
||||
border-collapse: separate;
|
||||
|
||||
thead {
|
||||
background: fi-var(table-thead-color);
|
||||
}
|
||||
|
||||
tbody {
|
||||
tr:nth-child(odd) {
|
||||
background: light-dark(color.adjust($table-background-color, $lightness: -2.25%), color.adjust($table-background-color-dark, $lightness: 2.75%));
|
||||
}
|
||||
tr:hover {
|
||||
background: light-dark(color.adjust($table-background-color, $lightness: -4.5%), color.adjust($table-background-color-dark, $lightness: 5.5%));
|
||||
}
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
padding: 0.3rem 1rem;
|
||||
border-inline-end: 1px solid fi-var(table-border-color);
|
||||
border-bottom: 1px solid fi-var(table-border-color);
|
||||
}
|
||||
|
||||
tr > :last-child {
|
||||
border-inline-end: none;
|
||||
}
|
||||
|
||||
> :last-child > tr:last-child > * {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
> caption {
|
||||
caption-side: top;
|
||||
padding: 0.5rem 1rem;
|
||||
text-align: center;
|
||||
font-weight: 600;
|
||||
font-size: 0.875em;
|
||||
border-bottom: 1px solid fi-var(table-border-color);
|
||||
border-radius: fi-var(global-border-radius) fi-var(global-border-radius) 0 0;
|
||||
|
||||
.table-number {
|
||||
&::before {
|
||||
content: attr(data-i18n-table) " " counter(table-counter);
|
||||
}
|
||||
|
||||
& + .table-caption {
|
||||
font-weight: normal;
|
||||
|
||||
&::before {
|
||||
content: "-";
|
||||
margin-inline: 0.25em;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sortable table styles
|
||||
&.is-sortable thead th.sort-header {
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
position: relative;
|
||||
padding-inline-end: 1.5rem;
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset-inline-end: 0.5rem;
|
||||
top: 50%;
|
||||
translate: 0 -50%;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-inline: 4px solid transparent;
|
||||
border-block: 4px solid transparent;
|
||||
opacity: 0.3;
|
||||
transition: all 0.2s, translate 0.2s;
|
||||
}
|
||||
|
||||
&:hover::after {
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
&.sort-asc::after,
|
||||
&.sort-desc::after {
|
||||
opacity: 1;
|
||||
border-block-end: 5px solid fi-var(global-font-color);
|
||||
border-block-start: 0;
|
||||
}
|
||||
|
||||
&.sort-desc::after {
|
||||
rotate: 180deg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -735,7 +735,7 @@ enable = false
|
||||
# Disclaimer type.
|
||||
# available values: ["ai", "repost", "original", "custom"]
|
||||
type = "ai"
|
||||
# Custom disclaimer content (optional, uses i18n default if empty).
|
||||
# Custom disclaimer content (optional, uses I18n default if empty).
|
||||
content = ""
|
||||
|
||||
# Display a message at the beginning of an article to warn the reader that its content might be expired.
|
||||
@@ -760,6 +760,13 @@ enable = false
|
||||
# Only enable in main section pages (default is posts).
|
||||
only_main_section = true
|
||||
|
||||
# {{< version 1.0.0 >}} Table configuration.
|
||||
[params.table]
|
||||
# Whether to enable auto table numbering.
|
||||
number = false
|
||||
# Whether to enable table sorting.
|
||||
sort = true
|
||||
|
||||
# Mathematical formulas configuration.
|
||||
# See: [Formula](https://fixit.lruihao.cn/docs/content-management/markdown-syntax/extended/#formula)
|
||||
[params.math]
|
||||
|
||||
@@ -89,6 +89,7 @@ valinePlaceholder = "تعليقك ..."
|
||||
|
||||
# === Assets ===
|
||||
[assets]
|
||||
table = "جدول"
|
||||
search = "بحث"
|
||||
searchPlaceholder = "ابحث في العناوين أو المحتوى ..."
|
||||
searchIn = "ابحث في {{ . }}"
|
||||
|
||||
@@ -88,6 +88,7 @@ valinePlaceholder = "Ihr Kommentar ..."
|
||||
|
||||
# === Assets ===
|
||||
[assets]
|
||||
table = "Tabelle"
|
||||
search = "Suche"
|
||||
searchPlaceholder = "Suche nach Titel und Inhalt..."
|
||||
searchIn = "Suche in {{ . }}"
|
||||
|
||||
@@ -88,6 +88,7 @@ valinePlaceholder = "Your comment ..."
|
||||
|
||||
# === Assets ===
|
||||
[assets]
|
||||
table = "Table"
|
||||
search = "Search"
|
||||
searchPlaceholder = "Search titles or contents ..."
|
||||
searchIn = "Search in {{ . }}"
|
||||
|
||||
@@ -88,6 +88,7 @@ valinePlaceholder = "Tu comentario ..."
|
||||
|
||||
# === Assets ===
|
||||
[assets]
|
||||
table = "Tabla"
|
||||
search = "Buscar"
|
||||
searchPlaceholder = "Busca títulos o contenido..."
|
||||
searchIn = "Buscar en {{ . }}"
|
||||
|
||||
@@ -89,6 +89,7 @@ valinePlaceholder = "نظر شما ..."
|
||||
|
||||
# === Assets ===
|
||||
[assets]
|
||||
table = "جدول"
|
||||
search = "جستجو"
|
||||
searchPlaceholder = "جستجوی عناوین یا محتوا ..."
|
||||
searchIn = "جستجو در {{ . }}"
|
||||
|
||||
@@ -88,6 +88,7 @@ valinePlaceholder = "Votre commentaire ..."
|
||||
|
||||
# === Assets ===
|
||||
[assets]
|
||||
table = "Tableau"
|
||||
search = "Chercher"
|
||||
searchPlaceholder = "Rechercher des titres, des contenus..."
|
||||
searchIn = "Rechercher dans {{ . }}"
|
||||
|
||||
@@ -89,6 +89,7 @@ valinePlaceholder = "आपकी टिप्पणी ..."
|
||||
|
||||
# === Assets ===
|
||||
[assets]
|
||||
table = "तालिका"
|
||||
search = "खोज"
|
||||
searchPlaceholder = "शीर्षक या सामग्री खोजें ..."
|
||||
searchIn = "{{ . }} में खोजें"
|
||||
|
||||
@@ -88,6 +88,7 @@ valinePlaceholder = "Il tuo commento ..."
|
||||
|
||||
# === Assets ===
|
||||
[assets]
|
||||
table = "Tabella"
|
||||
search = "Cerca"
|
||||
searchPlaceholder = "Cerca il titolo o il contenuto dell'articolo ..."
|
||||
searchIn = "Cerca in"
|
||||
|
||||
@@ -86,6 +86,7 @@ valinePlaceholder = "あなたのコメント……"
|
||||
|
||||
# === Assets ===
|
||||
[assets]
|
||||
table = "テーブル"
|
||||
search = "検索"
|
||||
searchPlaceholder = "タイトルまたは内容を検索..."
|
||||
searchIn = "{{ . }} で検索"
|
||||
|
||||
@@ -86,6 +86,7 @@ valinePlaceholder = "당신의 댓글……"
|
||||
|
||||
# === Assets ===
|
||||
[assets]
|
||||
table = "표"
|
||||
search = "검색"
|
||||
searchPlaceholder = "제목 또는 내용을 검색하세요..."
|
||||
searchIn = "{{ . }}에서 검색"
|
||||
|
||||
@@ -88,6 +88,7 @@ valinePlaceholder = "Twój komentarz ..."
|
||||
|
||||
# === Assets ===
|
||||
[assets]
|
||||
table = "Tabela"
|
||||
search = "Szukaj"
|
||||
searchPlaceholder = "Wyszukaj tytuł lub treść artykułu ..."
|
||||
searchIn = "Szukaj w {{ . }}"
|
||||
|
||||
@@ -89,6 +89,7 @@ valinePlaceholder = "O seu comentário..."
|
||||
|
||||
# === Assets ===
|
||||
[assets]
|
||||
table = "Tabela"
|
||||
search = "Pesquisa"
|
||||
searchPlaceholder = "Pesquisar títulos ou conteúdos..."
|
||||
searchIn = "Pesquisar em {{ . }}"
|
||||
|
||||
@@ -88,6 +88,7 @@ valinePlaceholder = "Comentariul dvs ..."
|
||||
|
||||
# === Assets ===
|
||||
[assets]
|
||||
table = "Tabelă"
|
||||
search = "Căutare"
|
||||
searchPlaceholder = "Căutarea titlului sau conținutului articolului ..."
|
||||
searchIn = "Căutare în {{ . }}"
|
||||
|
||||
@@ -88,6 +88,7 @@ valinePlaceholder = "Ваш комментарий ..."
|
||||
|
||||
# === Assets ===
|
||||
[assets]
|
||||
table = "Таблица"
|
||||
search = "Поиск"
|
||||
searchPlaceholder = "Поиск заголовков или содержимого ..."
|
||||
searchIn = "Поиск в {{ . }}"
|
||||
|
||||
@@ -88,6 +88,7 @@ valinePlaceholder = "Ваш коментар ..."
|
||||
|
||||
# === Assets ===
|
||||
[assets]
|
||||
table = "Табела"
|
||||
search = "Претрага"
|
||||
searchPlaceholder = "Претражи наслове или садржај..."
|
||||
searchIn = "Претражи у {{ . }}"
|
||||
|
||||
@@ -89,6 +89,7 @@ valinePlaceholder = "آپ کا تبصرہ ..."
|
||||
|
||||
# === Assets ===
|
||||
[assets]
|
||||
table = "جدول"
|
||||
search = "تلاش"
|
||||
searchPlaceholder = "عنوان یا مواد میں تلاش کریں ..."
|
||||
searchIn = "{{ . }} میں تلاش کریں"
|
||||
|
||||
@@ -87,6 +87,7 @@ valinePlaceholder = "Bình luận của bạn ..."
|
||||
|
||||
# === Assets ===
|
||||
[assets]
|
||||
table = "Bảng"
|
||||
search = "Tìm kiếm"
|
||||
searchPlaceholder = "Tìm tiêu đề hoặc nội dung..."
|
||||
searchIn = "Tìm kiếm trong {{ . }}"
|
||||
|
||||
@@ -86,6 +86,7 @@ valinePlaceholder = "你的评论……"
|
||||
|
||||
# === Assets ===
|
||||
[assets]
|
||||
table = "表"
|
||||
search = "搜索"
|
||||
searchPlaceholder = "搜索文章标题或内容……"
|
||||
searchIn = "在 {{ . }} 中搜索"
|
||||
|
||||
@@ -86,6 +86,7 @@ valinePlaceholder = "你的評論……"
|
||||
|
||||
# === Assets ===
|
||||
[assets]
|
||||
table = "表"
|
||||
search = "搜尋"
|
||||
searchPlaceholder = "搜尋文章標題或內容……"
|
||||
searchIn = "在 {{ . }} 中搜尋"
|
||||
|
||||
@@ -1,15 +1,40 @@
|
||||
{{- /*
|
||||
Add a table wrapper to better style overflow tables
|
||||
The reset of the template is the same as the default render-table.html
|
||||
Custom table render hook for FixIt theme.
|
||||
- Wraps tables in a scrollable container
|
||||
- Supports auto-numbering via CSS counters (config: params.table.number)
|
||||
- Supports client-side sorting (config: params.table.sort)
|
||||
- Supports table captions via Markdown attribute {caption="..."}
|
||||
- Per-table override via Markdown attributes (e.g., {number=false, sort=false})
|
||||
|
||||
See https://gohugo.io/render-hooks/tables/
|
||||
*/ -}}
|
||||
{{- $pageConfig := dict "Page" .Page "Key" "table" | partial "function/param.html" | merge .Attributes -}}
|
||||
{{- $config := .Attributes | merge $pageConfig -}}
|
||||
{{- $caption := .Attributes.caption -}}
|
||||
|
||||
{{- $attrs := "" -}}
|
||||
{{- if $config.number }}
|
||||
{{- $attrs = printf "%s data-table-numbered" $attrs }}
|
||||
{{- end -}}
|
||||
{{- if $config.sort }}
|
||||
{{- $attrs = printf "%s data-sortable" $attrs }}
|
||||
{{- .Page.Store.Set "hasTableSort" true }}
|
||||
{{- end -}}
|
||||
{{- range $k, $v := .Attributes }}
|
||||
{{- if and $v (ne $k "number") (ne $k "caption") (ne $k "sort") }}
|
||||
{{- $attrs = printf "%s %s=%q" $attrs $k $v }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
{{- $attrs = partial "function/trim.html" $attrs -}}
|
||||
|
||||
<div class="table-wrapper">
|
||||
<table
|
||||
{{- range $k, $v := .Attributes }}
|
||||
{{- if $v }}
|
||||
{{- printf " %s=%q" $k $v | safeHTMLAttr }}
|
||||
{{- end }}
|
||||
{{- end }}>
|
||||
<table {{ $attrs | safeHTMLAttr }}>
|
||||
{{- if or $config.number $caption }}
|
||||
<caption>
|
||||
{{- if $config.number }}<span class="table-number" data-i18n-table="{{ T `assets.table` }}"></span>{{ end -}}
|
||||
{{- with $caption }}<span class="table-caption">{{ . }}</span>{{ end -}}
|
||||
</caption>
|
||||
{{- end -}}
|
||||
<thead>
|
||||
{{- range .THead }}
|
||||
<tr>
|
||||
|
||||
@@ -267,6 +267,11 @@
|
||||
{{- dict "Source" "js/lib/watermark.ts" "Build" true "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- /* Table Sort */ -}}
|
||||
{{- if .Store.Get "hasTableSort" -}}
|
||||
{{- dict "Source" "js/lib/table-sort.ts" "Build" true "Fingerprint" $fingerprint "Defer" true | dict "Page" . "Data" | partial "store/script.html" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- /* Content Decryption */ -}}
|
||||
{{- $encryptPartial := .Store.Get "hasEncryptor" -}}
|
||||
{{- if .Params.password | or $encryptPartial -}}
|
||||
|
||||
Reference in New Issue
Block a user