Compare commits

..

1 Commits

Author SHA1 Message Date
Cell c91c0c8d52 ♻️ Refactor: refactor reading progress with css animation 2025-03-06 15:02:41 +08:00
2074 changed files with 14244 additions and 41552 deletions
-21
View File
@@ -1,21 +0,0 @@
FROM mcr.microsoft.com/devcontainers/javascript-node:24
# Install Hugo Extended
ARG HUGO_VERSION
RUN curl -sLJO "https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.tar.gz" \
&& tar -C /usr/local/bin -xf "hugo_extended_${HUGO_VERSION}_linux-amd64.tar.gz" hugo \
&& rm "hugo_extended_${HUGO_VERSION}_linux-amd64.tar.gz"
# Install Dart Sass
ARG DART_SASS_VERSION
RUN curl -sLJO "https://github.com/sass/dart-sass/releases/download/${DART_SASS_VERSION}/dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz" \
&& tar -C /usr/local -xf "dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz" \
&& ln -s /usr/local/dart-sass/sass /usr/local/bin/sass \
&& rm "dart-sass-${DART_SASS_VERSION}-linux-x64.tar.gz"
# Install Go
ARG GO_VERSION
RUN curl -sLJO "https://go.dev/dl/go${GO_VERSION}.linux-amd64.tar.gz" \
&& tar -C /usr/local -xf "go${GO_VERSION}.linux-amd64.tar.gz" \
&& rm "go${GO_VERSION}.linux-amd64.tar.gz"
ENV PATH="/usr/local/go/bin:${PATH}"
-27
View File
@@ -1,27 +0,0 @@
{
"name": "FixIt Theme",
"build": {
"dockerfile": "Dockerfile",
"args": {
"HUGO_VERSION": "0.161.0",
"DART_SASS_VERSION": "1.99.0",
"GO_VERSION": "1.24.4"
}
},
"postCreateCommand": "pnpm install",
"customizations": {
"vscode": {
"extensions": [
"budparr.language-hugo-vscode",
"kaellarkin.hugo-shortcode-syntax",
"lruihao.hugo-partials-refs",
"tamasfe.even-better-toml",
"casualjim.gotemplate",
"SomewhatStationery.some-sass",
"gruntfuggly.todo-tree",
"antfu.unocss",
"antfu.iconify"
]
}
}
}
-9
View File
@@ -1,9 +0,0 @@
root = true
[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
+35 -39
View File
@@ -1,55 +1,51 @@
name: Bug Report
description: Create a report to help us improve
title: '[Bug report] '
name: "Bug Report 错误报告"
description: "Create a bug report 创建一个错误报告"
title: "[BUG] Some problem ..."
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to fill out this bug report!
- type: textarea
id: bug-description
id: describe
attributes:
label: Description
description: A clear and concise description of what the bug is. If applicable, add screenshots to help explain your problem. If you intend to submit a PR for this issue, tell us in the description. Thanks!
placeholder: Bug description
validations:
required: true
- type: input
id: reproduction
label: Describe the bug 描述你遇到的错误
description: |
A clear and concise description of what the bug is.
一段简短的对于你遇到的错误的描述。
- type: textarea
id: expected
attributes:
label: Reproduction
description: Please provide a link to a repo that can reproduce the problem you ran into. A [minimal reproduction](https://stackoverflow.com/help/minimal-reproducible-example) is required.
placeholder: Reproduction
validations:
required: true
- type: dropdown
id: installation-method
label: Expected behavior 期待的行为
description: |
A clear and concise description of what you expected to happen.
一段简短的对于你期待的行为的描述。
- type: textarea
id: screenshots
attributes:
label: Installation Method
description: Select the installation method you used.
options:
- Hugo Module
- Git Submodule
- Git Clone
- Manual
- Other
validations:
required: true
label: Screenshots 屏幕截图
description: |
If applicable, add screenshots to help explain your problem.
如果可以的话,提供屏幕截图对解决问题很有帮助。
- type: textarea
id: environment
attributes:
label: Build Environment
label: Build Environment 构建环境
description: |
Please try to use Hugo **extended** version before opening the issue.
请在创建 issue 之前尝试使用 Hugo **extended** 版本。
placeholder: |
- Theme version/commit [e.g. 0.2.0, 2ccba79]
- Hugo version [e.g. 0.147.0]
- OS: [e.g. Windows 10, macOS, Ubuntu]
validations:
required: true
- Theme version/commit [e.g. 0.2.0, 2ccba79]
- Hugo version [e.g. 0.69.0]
- type: textarea
id: preview
attributes:
label: Preview Environment 预览环境
placeholder: |
- OS: [e.g. Windows 10, macOS, Ubuntu, iOS, Android]
- Browser [e.g. Chrome, Safari, Firefox]
- type: textarea
id: additional
attributes:
label: Additional Information
label: Additional Information 补充信息
description: |
Configuration files or front matter code snippets that may help us understand the issue.
Configuration files or front matter code ...
配置文件或者前置参数的代码……
+7 -6
View File
@@ -1,8 +1,9 @@
blank_issues_enabled: false
blank_issues_enabled: true
contact_links:
- name: Questions
- name: Questions 问题讨论
url: https://github.com/hugo-fixit/FixIt/discussions/new
about: Please ask questions in Discussion.
- name: Theme Documentation
url: https://fixit.lruihao.cn/
about: Please read the documentation carefully.
about: Please ask questions in Discussion. 请在讨论中提问。
- name: Theme Documentation 主题文档
url: https://fixit.lruihao.cn/documentation/
about: Please read the documentation carefully. 请先仔细阅读主题文档。
+21 -34
View File
@@ -1,35 +1,22 @@
name: Feature Request
description: Suggest an idea for this project
title: '[Feature request] '
name: "Feature request 功能请求"
description: "Suggest an idea for this project 为这个项目提供一个建议"
title: "[FEATURE] Some feature"
labels: ["enhancement"]
body:
- type: markdown
attributes:
value: |
Thanks for your interest in the project and taking the time to fill out this feature request!
- type: textarea
id: feature-description
attributes:
label: Clear and concise description of the problem
description: As a user or developer using FixIt, what feature your want in details. If you intend to submit a PR for this issue, tell us in the description. Thanks!
placeholder: Feature description
validations:
required: true
- type: textarea
id: suggested-solution
attributes:
label: Suggested solution
description: We could provide following implementation...
placeholder: Suggested solution
validations:
required: true
- type: textarea
id: alternative
attributes:
label: Alternative
description: Clear and concise description of any alternative solutions or features you've considered.
placeholder: Alternative solution
- type: textarea
id: additional-context
attributes:
label: Additional context
description: Any other context or screenshots about the feature request here.
- type: textarea
id: describe
attributes:
label: Describe the feature you want 描述你的功能需求
description: |
Please submit new issues for different features.
请针对不同的功能建议提交新的 issue。
placeholder: |
I recommend adding this feature ...
我希望添加这样的一个功能……
- type: textarea
id: reference
attributes:
label: Useful reference 有价值的参考
description: |
If available, provide useful links to fulfill the feature.
如果可以的话,提供实现这个功能的相关参考链接。
-26
View File
@@ -1,26 +0,0 @@
<!--
Thank you for contributing!
Before submitting the PR, please make sure you do the following:
- Read the [Contributing Guidelines](https://github.com/hugo-fixit/FixIt/blob/main/CONTRIBUTING.md).
- Provide a description in this PR that addresses **what** the PR is solving. If this PR is going to solve an existing issue, please reference the issue (e.g. `close #123`).
-->
### Description
<!-- Please insert your description here and provide especially info about the "what" this PR is solving -->
### What is the purpose of this pull request? <!-- (put an "X" next to an item) -->
- [ ] Bug fix
- [ ] New feature
- [ ] Other
### Screenshots
<!-- If your PR includes UI changes, please provide before/after screenshots. If there are any other images that add context to the PR, add them here as well -->
**Before**
**After**
+2 -2
View File
@@ -1,5 +1,5 @@
name: CodeQL config
name: "CodeQL config"
paths-ignore:
- assets/lib/**
- assets/js/lib/mermaid.js
- docs/**
-104
View File
@@ -1,104 +0,0 @@
# FixIt Coding Standards and Guidelines
This document defines the detailed coding standards for the FixIt theme project. For project overview, architecture, and development commands, see [CLAUDE.md](../../CLAUDE.md).
## SCSS Coding Standards
### Naming
- **CSS classes**: BEM or semantic naming (`header-desktop`, `menu-item`, `post-tag`)
- **SCSS variables**: hyphen-separated, semantic (`$global-font-family`, `$code-background-color`)
- **CSS custom properties**: prefixed with `fi-` / `--fi-`
### SCSS Guidelines
- Use 2-space indentation
- Use CSS variables for theme switching support
- Prefer relative units (rem, em, %) over absolute units
- Use SCSS variables for colors — no hardcoded values
- Keep selector nesting shallow
## UnoCSS Guidelines
- Use UnoCSS atomic classes for common utilities (`hidden`, `me-1`, `text-center`, etc.)
- Theme colors: `bg-primary`, `text-success`, `text-danger`, etc. (mapped via `@theme` in `uno.config.ts`)
- Responsive: `sm:` (>=680px), `md:` (>=960px), `lg:` (>=1200px), `xl:` (>=1440px). Use `max-sm:` for xs (<680px)
- Wrap SVG elements with `<!-- @unocss-skip-start -->` / `<!-- @unocss-skip-end -->` to avoid false positives from `d` attribute values
- Dynamically generated classes (e.g., `order-*`) must be added to `safelist` in `uno.config.ts`
- Run `pnpm unocss` after modifying `uno.config.ts` or templates that use UnoCSS classes
## TypeScript Coding Standards
### Architecture
Service-class architecture with direct constructor calls:
- **`TypedEventBus`** (`core/event-bus.ts`) — Module-level singleton (`eventBus`) wrapping DOM `CustomEvents` with typed event map.
- **Service interfaces** (`core/tokens.ts`) — Typed contracts for each module (`CoreService`, `ThemeService`, `CodeService`, etc.).
- **Module classes** (`modules/*.ts`) — Each module implements its service interface. Dependencies are constructor-injected.
### Module Pattern
```typescript
export class ExampleModule implements ExampleService {
#privateState: any // ES6 # private fields, not _ prefix
constructor(private readonly core: CoreService) {}
publicMethod(): void { /* ... */ }
#privateHelper(): void { /* ... */ }
}
```
### Key Rules
- Use ES6 `#` private fields — not TypeScript `private` with `_` prefix
- Keep modules focused: one module per file, one service interface per module
- Import the shared `eventBus` singleton from `core/event-bus` for cross-module communication
- Constructor injection for dependencies — no global state access
- `window.fixit` exposes a typed public API (`FixItPublicAPI`) for user custom scripts
- Comment style: follow [TSDoc](https://tsdoc.org/) conventions
### Utilities
- Pure functions only in `utils/` — no side effects, no DOM state
- Re-export everything through `utils/index.ts`
## Hugo Template Standards
### Conventions
- **Variable naming**: camelCase (`$footerConfig`, `$fingerprint`)
- **Comments**: Hugo syntax `{{- /* comment */ -}}`
- **Translation**: Use `T` function for i18n (`{{ T "header.switchTheme" }}`)
- **Whitespace**: Use `{{- -}}` trim markers to control whitespace output
### Hugo Template Guidelines
- Use `partialCached` for expensive partials that don't change per page
- Use `.Site.Store` for shared computed values (e.g. fingerprint)
- Check `hugo.IsProduction` before adding analytics or minification
## Git Workflow
### Commit Convention
Follows [Conventional Commits](https://www.conventionalcommits.org/):
```
<type>(<scope>): <subject>
```
Types: `feat`, `fix`, `refactor`, `chore`, `docs`, `perf`, `style`, `test`, `ci`, `build`
Scopes: `workflow`, `archetypes`, `assets`, `i18n`, `layouts`, `config`, or specific directories.
### Pre-commit Hooks
Pre-commit runs: versioning (dev mode), typecheck, lint-staged (eslint --fix on staged files).
## Browser Compatibility
- Target modern browsers
- Use progressive enhancement for advanced features
- Prefer feature detection over browser detection
+20 -25
View File
@@ -1,39 +1,34 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: npm # See documentation for possible values
directory: / # Location of package manifests
- package-ecosystem: "npm" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: monthly
interval: "monthly"
open-pull-requests-limit: 1000
assignees:
- Lruihao
- "Lruihao"
labels:
- dependencies
ignore:
- dependency-name: '@types/node'
update-types:
- 'version-update:semver-major'
groups:
npm-development:
dependency-type: development
update-types:
- minor
- patch
npm-production:
dependency-type: production
update-types:
- patch
- package-ecosystem: github-actions
directory: /
- "dependencies"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: monthly
interval: "monthly"
open-pull-requests-limit: 1000
assignees:
- Lruihao
- "Lruihao"
labels:
- dependencies
- "dependencies"
- package-ecosystem: "gitsubmodule"
directory: "/"
schedule:
interval: "weekly"
open-pull-requests-limit: 1000
assignees:
- "Lruihao"
labels:
- "dependencies"
-19
View File
@@ -1,19 +0,0 @@
changelog:
exclude:
labels:
- ignore-for-release
authors:
- dependabot
categories:
- title: New features
labels:
- feature
- title: Enhancement
labels:
- enhancement
- title: Fixes
labels:
- bug
- title: Other Changes
labels:
- '*'
+21
View File
@@ -0,0 +1,21 @@
name: Hugo build check
on:
pull_request:
branches: [ main ]
workflow_dispatch:
jobs:
Actions-Hugo-Check:
runs-on: ubuntu-latest
steps:
- name: Check out repository code
uses: actions/checkout@v4
with:
submodules: recursive # Fetch Hugo themes (true OR recursive)
fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod
- name: Setup Hugo
uses: peaceiris/actions-hugo@v3
with:
hugo-version: ${{ vars.HUGO_VERSION || 'latest' }}
extended: true
- name: Build Hugo static files
run: hugo --source=demo --gc --minify --logLevel info
+28 -28
View File
@@ -9,7 +9,7 @@
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: CodeQL
name: "CodeQL"
on:
push:
@@ -19,7 +19,7 @@ on:
branches:
- main
schedule:
- cron: '30 18 * * 5'
- cron: "30 18 * * 5"
jobs:
analyze:
@@ -29,44 +29,44 @@ jobs:
strategy:
fail-fast: false
matrix:
language: [javascript]
language: [ "javascript" ]
# CodeQL supports [ "cpp", "csharp", "go", "java", "javascript", "python" ]
# Learn more:
# https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
steps:
- name: Check out repository code
uses: actions/checkout@v7
with:
submodules: true # Fetch Hugo themes (true OR recursive)
fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod
- name: Check out repository code
uses: actions/checkout@v4
with:
submodules: true # Fetch Hugo themes (true OR recursive)
fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v4.37.3
with:
languages: ${{ matrix.language }}
config-file: ./.github/configs/codeql.yml
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
config-file: ./.github/configs/codeql.yml
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# queries: ./path/to/local/query, your-org/your-repo/queries@main
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v4.37.3
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v3
# ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ️ Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
# and modify them (or add more) to build your code if your project
# uses a compiled language
# - run: |
# make bootstrap
# make release
#- run: |
# make bootstrap
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v4.37.3
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
+5 -12
View File
@@ -5,16 +5,14 @@ on:
workflow_dispatch: # Run workflow manually (without waiting for the cron to be called), through the GitHub Actions Workflow page directly
permissions:
contents: write # To write the generated contents to the readme
pull-requests: write # To create a pull request
jobs:
generate-component-list:
if: github.repository == 'hugo-fixit/FixIt'
name: Update this repo's README with the list of hugo-fixit theme components
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
uses: actions/checkout@v4
- name: Generate hugo-fixit component list
uses: hugo-fixit/action-component-list@v1
env:
@@ -23,13 +21,8 @@ jobs:
comment_tag_name: HUGO_FIXIT_COMPONENTS
readme_path: 'README.md,README.zh-cn.md'
template: "- [{$repo.name}]({$repo.html_url})\\\n {$repo.description}"
- name: Create Pull Request
uses: peter-evans/create-pull-request@v8
- name: Commit changes
uses: stefanzweifel/git-auto-commit-action@v5
with:
title: Update hugo-fixit component list
commit-message: 'docs(readme): update hugo-fixit component list'
body: This PR updates the hugo-fixit component list in the README.
base: main
branch: update-component-list
labels: documentation
reviewers: Lruihao
commit_message: ':memo: Docs: update hugo-fixit component list'
commit_author: 'github-actions[bot] <github-actions[bot]@users.noreply.github.com>'
-39
View File
@@ -1,39 +0,0 @@
name: Update Chroma lexer map
on:
schedule:
# Run at 00:00, on day 1 of the month
- cron: '0 0 1 * *'
workflow_dispatch:
permissions:
contents: write
pull-requests: write
jobs:
update:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v7
- uses: pnpm/action-setup@v6
- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version-file: .nvmrc
cache: pnpm
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Generate lexer map
run: pnpm gen:lexers
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create Pull Request
uses: peter-evans/create-pull-request@v8
with:
title: 'chore(assets): regenerate chroma lexer map'
commit-message: 'chore(assets): regenerate chroma lexer map'
body: |
Auto-generated `assets/scss/core/maps/_chroma-lexers.scss` via `pnpm gen:lexers`.
Data from: [alecthomas/chroma](https://github.com/alecthomas/chroma/tree/master/lexers) latest release.
branch: auto/chroma-lexers
base: main
labels: dependencies
reviewers: Lruihao
-50
View File
@@ -1,50 +0,0 @@
name: Update libraries from npm
on:
schedule:
# Run at 00:00, on day 1 of the month
- cron: '0 0 1 * *'
workflow_dispatch:
permissions:
contents: write
pull-requests: write
jobs:
prepare:
runs-on: ubuntu-latest
outputs:
libraries: ${{ steps.list.outputs.libraries_json }}
steps:
- name: Checkout
uses: actions/checkout@v7
- name: List libraries
id: list
uses: hugo-fixit/librarybot@v1
with:
mode: list
update:
needs: prepare
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
library: ${{ fromJson(needs.prepare.outputs.libraries) }}
steps:
- name: Checkout
uses: actions/checkout@v7
- name: Update library
id: update
uses: hugo-fixit/librarybot@v1
with:
mode: update
library: ${{ matrix.library }}
- name: Create Pull Request
if: steps.update.outputs.changed == 'true'
uses: peter-evans/create-pull-request@v8
with:
title: 'chore(deps): bump ${{ steps.update.outputs.package }} from `${{ steps.update.outputs.from_version }}` to `${{ steps.update.outputs.to_version }}`'
commit-message: 'chore(deps): bump ${{ steps.update.outputs.package }} from `${{ steps.update.outputs.from_version }}` to `${{ steps.update.outputs.to_version }}`'
body: |
Automated update of `${{ steps.update.outputs.package }}` from `${{ steps.update.outputs.from_version }}` to `${{ steps.update.outputs.to_version }}`.
branch: ${{ steps.update.outputs.pr_branch }}
base: main
labels: dependencies
reviewers: Lruihao
-43
View File
@@ -1,43 +0,0 @@
name: Publish @hugo-fixit/encrypt
on:
push:
tags:
- 'encrypt-v*.*.*'
workflow_dispatch:
permissions:
contents: read
id-token: write
concurrency:
group: publish-encrypt-${{ github.ref }}
cancel-in-progress: false
jobs:
publish:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v7
- uses: pnpm/action-setup@v6
- name: Setup Node.js
uses: actions/setup-node@v7
with:
node-version-file: .nvmrc
registry-url: 'https://registry.npmjs.org'
cache: pnpm
scope: '@hugo-fixit'
- name: Update npm
run: npm install -g npm@latest
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build package
run: pnpm -F encrypt build
- name: Publish package to npm
working-directory: packages/encrypt
run: npm publish --access public --provenance
+23 -26
View File
@@ -1,49 +1,46 @@
# This is a basic workflow to help you get started with Actions
name: Release for new tag
# Controls when the action will run.
on:
# Triggers the workflow on push or pull request events but only for the main branch
push:
tags:
- 'v*.*.*'
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
release:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- name: Checkout repository
uses: actions/checkout@v7
uses: actions/checkout@v4
with:
fetch-depth: 0 # Fetch all history for generating release notes
fetch-depth: 0 # Fetch all history for generating release notes
- uses: pnpm/action-setup@v6
- name: Setup Node.js
uses: actions/setup-node@v7
uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
cache: pnpm
- name: Install fixit-cli
run: pnpm install -g fixit-cli
- name: Split theme configuration
node-version: 18
- name: Install dependencies and generate release notes
run: |
fixit split
tar -zcvf config_toml.tar.gz config
rm -rf config
fixit split -y
tar -zcvf config_yaml.tar.gz config
rm -rf config
- name: Generate release notes
run: |
pnpm install --frozen-lockfile
pnpm changelog --starting-version ${{ github.ref_name }}
npm install
npm run release -- --starting-version ${{ github.ref_name }}
sed -i '1,4d' CHANGELOG.md
- name: GitHub Release
uses: softprops/action-gh-release@v3
uses: softprops/action-gh-release@v2
with:
# Creates a draft release. Defaults to false
draft: true
body_path: CHANGELOG.md
files: |
config_toml.tar.gz
config_yaml.tar.gz
+7 -29
View File
@@ -1,40 +1,16 @@
# Hugo
.hugo_build.lock
jsconfig.json
.hugo_cache
# Hugo default output directory
public/
resources/
# packages
dist/
# Hugo
.hugo_build.lock
jsconfig.json
# NPM
node_modules/
.eslintcache
# VSCode
.vscode/*
!.vscode/extensions.json
!.vscode/settings.json
# Trae
.trae/
# Claude
.claude/
CLAUDE.local.md
.codegraph/
# Vercel
.vercel/
# Environment Variables
.env*.local
# Documentation
docs/
CHANGELOG.md
TODO.md
.vscode
# OS Files
## Windows
@@ -48,3 +24,5 @@ $RECYCLE.BIN/
## Linux
.directory
CHANGELOG.md
+1
View File
@@ -0,0 +1 @@
npx fixit-releaser version --dev
+2 -2
View File
@@ -1,2 +1,2 @@
tag-version-prefix=v
message=chore(release): %s
tag-version-prefix="v"
message=":bookmark: Chore(release): %s"
+1 -1
View File
@@ -1 +1 @@
v24
v18
-7
View File
@@ -1,7 +0,0 @@
{
"display": {
"access": ["public"],
"alias": false
},
"sort": ["group"]
}
-13
View File
@@ -1,13 +0,0 @@
{
"recommendations": [
"budparr.language-hugo-vscode",
"kaellarkin.hugo-shortcode-syntax",
"lruihao.hugo-partials-refs",
"tamasfe.even-better-toml",
"casualjim.gotemplate",
"SomewhatStationery.some-sass",
"gruntfuggly.todo-tree",
"antfu.unocss",
"antfu.iconify"
]
}
-93
View File
@@ -1,93 +0,0 @@
{
"todo-tree.tree.scanMode": "workspace only",
"files.associations": {
"*.template.ts": "gots",
"*.template.js": "gojs",
"*.template.scss": "gocss",
"*.template.svg": "html",
"**/plugin/script.html": "gohtml",
"**/layouts/**/*.json": "gojson",
"**/layouts/**/*.xml": "gohtml",
"**/layouts/**/*.md": "gotemplate"
},
// Disable the default formatter, use ESLint instead
"prettier.enable": false,
"editor.formatOnSave": false,
// Auto fix
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.organizeImports": "never"
},
// Silent the stylistic rules in you IDE, but still auto fix them
"eslint.rules.customizations": [
{
"rule": "style/*",
"severity": "off",
"fixable": true
},
{
"rule": "format/*",
"severity": "off",
"fixable": true
},
{
"rule": "*-indent",
"severity": "off",
"fixable": true
},
{
"rule": "*-spacing",
"severity": "off",
"fixable": true
},
{
"rule": "*-spaces",
"severity": "off",
"fixable": true
},
{
"rule": "*-order",
"severity": "off",
"fixable": true
},
{
"rule": "*-dangle",
"severity": "off",
"fixable": true
},
{
"rule": "*-newline",
"severity": "off",
"fixable": true
},
{
"rule": "*quotes",
"severity": "off",
"fixable": true
},
{
"rule": "*semi",
"severity": "off",
"fixable": true
}
],
// SCSS path resolution (Some Sass extension)
"somesass.workspace.loadPaths": ["assets/scss"],
"somesass.scss.links.enabled": true,
// Enable eslint for all supported languages
"eslint.validate": [
"go-html-template",
"javascript",
"typescript",
"html",
"markdown",
"json",
"json5",
"jsonc",
"yaml",
"toml",
"xml",
"css",
"scss"
]
}
-160
View File
@@ -1,160 +0,0 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
FixIt is a modern, responsive theme for the Hugo static site generator. Built with Hugo templates, SCSS, UnoCSS, and TypeScript.
## Development Commands
### Prerequisites
- Node.js >= 20
- Hugo Extended >= 0.161.0 (Dart Sass required)
- pnpm
### Development
```bash
pnpm install # Install dependencies
pnpm dev:demo # Start demo site dev server
pnpm dev:test # Start test site dev server
pnpm dev:docs # Start docs dev server (requires fixit-docs as sibling directory)
```
### Build
```bash
pnpm build:demo # Build demo site
pnpm build:test # Build test site
pnpm build # Build all sites (demo + test, merged into public/)
pnpm preview # Preview built site (requires build first)
```
### Code Generation
```bash
pnpm gen:lexers # Regenerate assets/scss/core/maps/_chroma-lexers.scss from Chroma source
```
### Code Quality
```bash
pnpm lint # Run ESLint
pnpm typecheck # Run TypeScript type checking
```
There are no unit tests. Verify changes by building `pnpm build:demo` or `pnpm build:test` and inspecting the output.
## Architecture
### Monorepo Structure
Root `package.json` is `@hugo-fixit/core`. pnpm workspaces include `apps/*` and `packages/*`:
- `apps/demo/` — Demo site (deployed to `demo.fixit.lruihao.cn`)
- `apps/test/` — Test site for exercising theme features
- `packages/shared` — Shared utilities (exports `workspaceRoot`, `fromRoot`, `runCommand`, `capitalize`, `consola`)
- `packages/versioning` — Version management (auto-updates version in `layouts/_partials/init/index.html` during pre-commit)
- `packages/integration` — Post-build: merges demo/test output into `public/`
- `packages/chroma-lexers` — Generates Chroma lexer SCSS map from GitHub
### JavaScript Module System (`assets/js/`)
Service-class architecture with direct constructor calls:
- **`main.ts`** — Entry point. Instantiates all modules with direct constructor calls, builds the typed `window.fixit` public API facade, and runs the init sequence on `DOMContentLoaded`.
- **`types/`** — TypeScript type definitions:
- `config.ts``FixItConfig` and all config sub-types.
- `ui.ts``FixItPublicAPI`, global `window` augmentation for third-party libs.
- `third-party.ts` — Types for vendored libraries.
- **`core/`** — Infrastructure layer:
- `event-bus.ts` — Typed event bus singleton wrapping DOM `CustomEvents`. Exports `eventBus` (module-level singleton) and `FixItEventMap` type.
- `tokens.ts` — Service interfaces (`CoreService`, `ThemeService`, `CodeService`, etc.) used for module constructor typing.
- **`modules/`** — Feature modules. Each is a class implementing its service interface. Dependencies are constructor-injected. Private state uses ES6 `#` fields. Modules: charts, code, content, core, encryption, events, menu, misc, search, theme, toc. `pagefind.ts` is a standalone factory consumed by `SearchModule`.
- **`utils/`** — Pure utility functions (no side effects, no DOM state). Re-exported from `utils/index.ts`.
- **`lib/`** — Third-party library wrappers (aplayer, echarts, file-tree, fixit-decryptor, lightgallery, mapbox, mathjax, mermaid, etc.). All import the shared `eventBus` singleton.
- **`head/`** — `color-scheme.ts` runs synchronously in `<head>` before body render to prevent flash of wrong theme.
- **`pages/`** — Page-specific scripts (e.g. `link.ts` for the link guard redirection page).
Cross-module communication uses the shared `eventBus` singleton, not direct module imports. The `window.fixit` facade exposes a typed public API for user custom scripts (`custom.ts`): theme control, scroll state, mask overlay management, content re-initialization, and the event bus.
### Hugo Templates (`layouts/`)
- **`_partials/`** — Reusable template components (organized into `init/`, `base/`, `function/`, `plugin/`, `single/`, `store/`)
- **`_shortcodes/`** — 31 custom shortcodes (admonition, aplayer, echarts, file-tree, mermaid, tabs, timeline, etc.)
- **`_markup/`** — 15 render hooks (code blocks, headings, images, links, tables, blockquote alerts, passthrough for math)
### Asset Pipeline
Hugo Pipes processes all assets. The key orchestration is in `_partials/base/assets.html`:
- **CSS**: `scss/main.scss` is the entry point importing `core/`, `pages/`, `widgets/`, `custom`. SCSS variables are configured via `hugo:vars` (user-configurable from `[params.appearance]`) and `hugo:vars/internal` (theme system config). UnoCSS utility classes are pre-built to `assets/css/unocss.css` (via `pnpm unocss`), loaded before the main SCSS bundle.
- **JS**: `_partials/function/js-build.html` wraps `js.Build` with minify-in-production defaults. Hugo's `@params` injection passes config values into TypeScript at build time.
- **Third-party libraries**: Stored in `assets/lib/` (vendored, not npm-managed). Tracked by `librarybot.yml` and updated weekly by the `hugo-fixit/librarybot` GitHub Action. Can be overridden via CDN config in `assets/data/cdn/jsdelivr.yml` or `unpkg.yml`.
### Theme Configuration
- **`hugo.toml`** — Default theme configuration (1700+ lines). Uses `_merge = "shallow"` to let user configs override without deep merging.
- **`theme.toml`** — Theme metadata
## Coding Standards
### SCSS (`assets/scss/`)
- CSS classes: BEM or semantic naming (`header-desktop`, `menu-item`)
- SCSS variables: hyphen-separated, semantic (`$global-font-family`)
- CSS custom properties: prefixed with `fi-` / `--fi-`
- Use `fi-var()` function to reference CSS custom properties (auto-adds `--fi-` prefix), never use `var(--fi-...)` directly
- Use CSS variables for theme switching; SCSS variables for colors (no hardcoded values)
- Prefer relative units (rem, em, %) over absolute units
- Keep selector nesting shallow
### UnoCSS (`assets/css/unocss.css`)
- Pre-built utility classes generated by `pnpm unocss` (config: `uno.config.ts`)
- Use atomic classes for common utilities (`hidden`, `me-1`, `text-center`, etc.)
- Theme colors mapped via `@theme`: `bg-primary`, `text-success`, `text-danger`, etc.
- Responsive breakpoints: `sm:` (>=680px), `md:` (>=960px), `lg:` (>=1200px), `xl:` (>=1440px). Use `max-sm:` for xs (<680px)
- Wrap SVG elements with `<!-- @unocss-skip-start -->` / `<!-- @unocss-skip-end -->` to avoid false positives from `d` attribute values
- `safelist` in `uno.config.ts` for dynamically generated classes (e.g., `order-*`, `sm:hidden`)
### TypeScript
- Use ES6 `#` private fields — not TypeScript `private` with `_` prefix
- One module per file, one service interface per module
- Constructor injection for dependencies — no global state access
- Import the shared `eventBus` singleton from `core/event-bus` — do not create new instances
- Pure functions only in `utils/` — no side effects, no DOM state
- Comment style: follow [TSDoc](https://tsdoc.org/) conventions
### Hugo Templates
- Variable naming: camelCase (`$footerConfig`, `$fingerprint`)
- Translation: use `T` function (`{{ T "header.switchTheme" }}`)
- Whitespace: use `{{- -}}` trim markers
- Use `partialCached` for expensive partials that don't change per page
- Use `.Site.Store` for shared computed values (e.g. fingerprint)
- Check `hugo.IsProduction` before adding analytics or minification
- Minimize `id` attribute usage — prefer class selectors for styling and JS queries. Reserve `id` for: `<label for>`, `aria-controls`/`aria-labelledby`, fragment anchors, or third-party library requirements
## Commit Convention
Follows [Conventional Commits](https://www.conventionalcommits.org/):
```
<type>(<scope>): <subject>
```
Types: `feat`, `fix`, `refactor`, `chore`, `docs`, `perf`, `style`, `test`, `ci`, `build`
Scopes: `workflow`, `archetypes`, `assets`, `i18n`, `layouts`, `config`, or specific directories.
## Pre-commit Hooks
Pre-commit runs: versioning (dev mode), typecheck, lint-staged (eslint --fix on staged files).
## ESLint
Uses `@antfu/eslint-config` with TypeScript support. Config at `eslint.config.ts`.
+10 -10
View File
@@ -17,23 +17,23 @@ diverse, inclusive, and healthy community.
Examples of behavior that contributes to a positive environment for our
community include:
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes,
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
- Focusing on what is best not just for us as individuals, but for the
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
- The use of sexualized language or imagery, and sexual attention or
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
- Other conduct which could reasonably be considered inappropriate in a
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
+52 -153
View File
@@ -2,31 +2,7 @@
Make sure that you follow [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) while contributing and engaging in the discussions.
## Prerequisites
Before you start contributing, make sure you have the following tools installed:
- **Hugo Extended** (>= 0.161.0) - The static site generator
- **Dart Sass** - Required for SCSS compilation
- **Node.js** (>= 22) - Required for package management and build tools
- **pnpm** - Package manager
You can check your installed versions:
```bash
hugo version
sass --version
node --version
pnpm --version
```
Check the Hugo environment information:
```bash
hugo env
```
## How to Contribute
## How to contribute to this project
First, fork this repository by clicking the fork button.
@@ -39,153 +15,76 @@ git clone https://github.com/hugo-fixit/FixIt.git && cd FixIt
Then, install the dev dependencies.
```bash
pnpm install
npm install
```
And now you are ready to go!
### Workflow
1. **Make your changes** in the appropriate directories
2. **Test locally** using `pnpm dev:demo` or `pnpm dev:test`
3. **Check code quality** with `pnpm lint` and `pnpm typecheck`
4. **Check different environments** with production builds (`pnpm build:demo` or `pnpm build:test`)
5. **Verify documentation** changes with `pnpm dev:docs` (if applicable)
6. **Commit your changes** following the commit message format below
### Commands
Here are some useful commands.
```bash
# Start demo site development server
pnpm dev:demo
# Start test site development server
pnpm dev:test
# Start documentation development server (requires fixit-docs as sibling directory)
pnpm dev:docs
# Build demo site
pnpm build:demo
# Build test site
pnpm build:test
# Build all sites
pnpm build
# Lint with ESLint
pnpm lint
# TypeScript type checking
pnpm typecheck
# Regenerate Chroma lexer map (assets/scss/core/maps/_chroma-lexers.scss)
pnpm gen:lexers
# Preview the built site locally (requires build first)
pnpm preview
# Build UnoCSS utility classes (pre-built, committed to repo)
pnpm unocss
# Watch mode for UnoCSS (for theme developers)
pnpm unocss:watch
# run a local debugging server with watch
npm run server
# run a local debugging server with watch in production environment
npm run server:production
```
> [!TIP]
>
> - Add `-e production` to the development command to check the production environment, e.g. `pnpm dev:test -e production`.
> - Add `-e debug` to enable debug mode (if applicable), e.g. `pnpm dev:test -e debug`.
> - For documentation-related theme changes, it is recommended to clone both `FixIt` and `fixit-docs` as sibling directories.
If you want to do docs-related theme changes, the simplest way is to have both `FixIt` and `fixit-docs` cloned as sibling directories, and then run:
### Pull Request
- Create a feature branch from `main`
- Make your changes with clear, focused commits
- Test your changes thoroughly
- Update documentation if needed
- Submit a pull request with a clear description
Finally, create a new pull request at <https://github.com/hugo-fixit/FixIt/pulls> to submit your contribution.
---
## Project Structure
Understanding the project structure will help you contribute more effectively:
```
FixIt/
├── apps/ # Minimal sites
│ ├── demo/ # Demo site
│ └── test/ # Test site
├── archetypes/ # Content templates
├── assets/ # Theme assets
│ ├── css/ # UnoCSS pre-built output (unocss.css)
│ ├── images/ # Image assets
│ ├── js/ # JavaScript files
│ ├── lib/ # Third-party libraries
│ └── scss/ # SCSS stylesheets
├── i18n/ # Internationalization files
├── layouts/ # Hugo template files
│ ├── _markup/ # Hugo render hooks
│ ├── _partials/ # Reusable template components
│ └── _shortcodes/ # Custom shortcodes
├── packages/ # Theme-related packages (pnpm workspaces)
│ ├── chroma-lexers/ # Chroma lexer SCSS map generator
│ ├── integration/ # Post-build site merging
│ ├── shared/ # Shared utilities
│ └── versioning/ # Version management (pre-commit)
├── static/ # Static files
├── hugo.toml # Default theme configuration
├── uno.config.ts # UnoCSS configuration
└── package.json # npm scripts and dependencies
```bash
npm run server:docs
```
## Git Commit Guidelines
Finally, create a new pull request at <https://github.com/hugo-fixit/FixIt/pulls> to submit your contribution 🎉
We follow the [Conventional Commits](https://www.conventionalcommits.org/) specification for commit messages. This enables automatic changelog generation using our custom template: [conventional.hbs](https://github.com/Lruihao/auto-changelog-plus/blob/main/settings/conventional.hbs).
## Git standard for developers
> [!NOTE]
>
> Commits in a PR will normally be squashed into one commit, so you don't need to rebase locally.
### Branches
### Commit Message Format
| Branch | Description |
| :------------- | :----------------------------------------------------- |
| main | _The development branch, may contain unstable updates_ |
| single feature | _The branch to enhancements or fixes_ |
```
<type>(<scope>): <subject>
^ ^ ^
| | |__ Subject: Concise description of the change (imperative mood, lowercase).
| |____________ Scope: The specific part of the codebase affected (optional but recommended).
|___________________ Type: Indicates the kind of change.
```
### Merge events
> [!NOTE]
>
> - Keep the subject line concise and ideally within 72 characters.
> - If the change is more than a sentence, add a body.
> - Do not include secrets (tokens/keys) or personal data in commit messages.
> - Do not invent issue/PR numbers or facts that are not present in the diff.
| event | merge |
| :------------- | :------------------------------------ |
| PR | **others:main => main:** `--rebase` |
| single feature | **feature branch => main:** `--merge` |
### Allowed Types
### Commit message
- `feat`: A new feature.
- `fix`: A bug fix.
- `refactor`: Code changes that neither fix a bug nor add a feature.
- `chore`: Changes to the build process, auxiliary tools, libraries, documentation generation etc.
- `docs`: Documentation only changes.
- Other conventional types like `perf`, `style`, `test`, `ci`, `build` are also acceptable.
#### Format
### Allowed Scopes
`[{emoji} ]{type}[({scope})]: {subject within 50 words}[ (#{issue/pull request})]`
- `workflow`: CI/CD workflow changes (`.github/workflows/`)
- `archetypes`: Content templates (`archetypes/`)
- `assets`: Changes to theme assets like CSS, JS (`assets/`)
- `i18n`: Internationalization and translation files (`i18n/`)
- `layouts`: Root-level Hugo template files (`layouts/*.html`)
- `config`: Theme configuration (`hugo.toml`, `theme.toml`)
- _(All top-level directories in the layouts and packages directories)_
- _(Consider adding other scopes as needed for better granularity)_
example:
### Examples
- :tada: Feat: add shortcode fixit-encryptor shortcode (#123)
- :arrow_up: Chore(libs): update Artalk from 2.2.12 to 2.3.4 (#150)
- `feat(_shortcodes): add mapbox zoom control options`
- `fix(_partials): avoid duplicate canonical link tags`
- `docs(i18n): update translation key naming guidelines`
- `ci(workflow): optimize preview deployment cache`
- `refactor(assets): split theme initialization into smaller modules`
#### Emoji
- <https://gitmoji.dev>
- [vscode plugin](https://github.com/maixiaojie/git-emoji-zh.git)
- utools plugin `GitEmoji`
#### Message
| Emoji | Type | Example | Description (No Ambiguous) |
| :-------------------------------------------- | :------- | :----------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------- |
| :tada:<br>:sparkles: | Feat | Feat: add {feature} | new feature |
| :truck: | | Feat: adjust/migrate {feature name}, {change details} | For the adjustment feature, it is necessary to describe the current situation (before) and after adjustment (after) |
| :fire: | | Feat: delete {feature name}, {deletion reason} | If the feature is deleted, the reason for deletion must be explained |
| :bug: <br>:construction: <br>:rotating_light: | Fix | Fix: fix {bug description} | Fix known bugs |
| :art: <br>:lipstick: <br>:pencil2: | Style | Style: Typesetting/CSS style {optimizing content} | Changes that do not affect code operation, such as code layout and style change |
| :recycle: | Refactor | Refactor: override {feature name} | It is neither a new function nor a code change to fix a bug. Simply rewriting the code of a function does not affect the function result |
| :zap: | Perf | Perf: improve performance {function name}, {improve content} | Optimize code performance |
| :rewind: | Revert | Revert: restore version {commit message of restore version} | Restore the version of one commit |
| :pencil:<br>:pencil2: | Docs | Docs: revise comments/update documents | Adjustment of documents and notes |
| :wrench: | Chore | Chore: update plugin version | Changes in the construction process or auxiliary tools |
> [!note]
> The change log is automatically generated based on the commit message.\
> Use `Chore` type or add `(ignore)` scope to ignore including in.
+1 -1
View File
@@ -2,7 +2,7 @@ The MIT License (MIT)
Copyright (c) 2018 LIUZHICHAO.COM
Copyright (c) 2019-2020 DILLONZQ.COM
Copyright (c) 2021-present Lruihao (https://lruihao.cn)
Copyright (c) 2021-2025 Lruihao (https://lruihao.cn)
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
+55 -78
View File
@@ -13,9 +13,9 @@
<a href="https://fixit.lruihao.cn/ecosystem/hugo-fixit/fixit/?lang=russian">Русский язык</a> |
<a href="https://fixit.lruihao.cn/ecosystem/hugo-fixit/fixit/?lang=spanish">Español</a> |
<a href="https://fixit.lruihao.cn/ecosystem/hugo-fixit/fixit/?lang=hindi">हिन्दी</a> |
<a href="https://fixit.lruihao.cn/ecosystem/hugo-fixit/fixit/?lang=deutsch">Deutsch</a> |
<a href="https://fixit.lruihao.cn/ecosystem/hugo-fixit/fixit/?lang=german">deutsch</a> |
<a href="https://fixit.lruihao.cn/ecosystem/hugo-fixit/fixit/?lang=korean">한국어</a> |
<a href="https://fixit.lruihao.cn/ecosystem/hugo-fixit/fixit/?lang=japanese">日本語</a>
<a href="https://fixit.lruihao.cn/ecosystem/hugo-fixit/fixit/?lang=japanese">しろうと</a>
</div>
<a title="FixIt website" href="https://fixit.lruihao.cn"><img align="right" alt="FixIt logo" width="70" height="70" src="https://avatars.githubusercontent.com/u/110414864?s=200&v=4"></a>
@@ -24,33 +24,33 @@
> It is based on the original [LoveIt](https://github.com/dillonzq/LoveIt) Theme, [KeepIt](https://github.com/Fastbyte01/KeepIt) Theme and [LeaveIt](https://github.com/liuzc/LeaveIt) Theme.
[![Build](https://img.shields.io/github/deployments/hugo-fixit/FixIt/Production?style=flat&label=Build&logo=vercel)](https://demo.fixit.lruihao.cn/)
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/hugo-fixit/FixIt?style=flat&label=Release&logo=github&include_prereleases)](https://github.com/hugo-fixit/FixIt/releases)
[![Hugo](https://img.shields.io/badge/Hugo-%5E0.161.0-ff4088?style=flat&logo=hugo)](https://gohugo.io/)
[![License](https://img.shields.io/github/license/hugo-fixit/FixIt?style=flat&label=License)](/LICENSE)
[![GitHub stars](https://img.shields.io/github/stars/hugo-fixit/FixIt?style=social)](https://github.com/hugo-fixit/FixIt)
[![Gitee star of FixIt](https://gitee.com/lruihao/FixIt/badge/star.svg)](https://gitee.com/lruihao/FixIt/stargazers)
> [!WARNING]
> **The `main` branch contains the v1 code. For upgrade instructions, see the [v1 migration guide](https://fixit.lruihao.cn/guides/upgrade-to-v1/).**\
> Version 1.0.0 is planned for release in **the first half of 2027**. Welcome to join the development and [discussion](https://github.com/orgs/hugo-fixit/discussions/723)!
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/hugo-fixit/FixIt?style=flat)](https://github.com/hugo-fixit/FixIt/releases)
[![Hugo](https://img.shields.io/badge/Hugo-%5E0.141.0-ff4088?style=flat&logo=hugo)](https://gohugo.io/)
[![License](https://img.shields.io/github/license/hugo-fixit/FixIt?style=flat)](/LICENSE)
[![Open Source Love](https://badges.frapsoft.com/os/v1/open-source.svg?v=103)](https://github.com/hugo-fixit/FixIt)
## Live Preview
<p align="center">
💟 <a href="https://fixit.lruihao.cn">Docs</a> | ❇️ <a href="https://demo.fixit.lruihao.cn/test/">Test</a> | 🚼 <a href="https://demo.fixit.lruihao.cn">Demo</a> | 🆕 <a href="https://hugo-fixit.github.io/hugo-fixit-starter/">Starter</a>
💟 <a href="https://fixit.lruihao.cn">Production</a> | ❇️ <a href="https://pre.fixit.lruihao.cn">Preview</a> | 🚼 <a href="https://demo.fixit.lruihao.cn">Demo</a> | 🆕 <a href="https://hugo-fixit.github.io/hugo-fixit-starter/">Starter</a>
<br>
<br>
More FixIt examples <a href="https://fixit.lruihao.cn/showcase/">here</a>.
</p>
## Why choose FixIt
I don't know why 🤷.
<!-- Too lazy to write... -->
## Usage
### Documentation
Head to the [Quick Start](https://fixit.lruihao.cn/docs/getting-started/quick-start/) page for a step-by-step guide on how to create a new website with FixIt.
Head to the [Quick Start](https://fixit.lruihao.cn/documentation/getting-started/quick-start/) page for a step-by-step guide on how to create a new website with FixIt.
Outline: [Installation](https://fixit.lruihao.cn/docs/installation/) ➜ [Getting Started](https://fixit.lruihao.cn/docs/getting-started/) ➜ [Content Management](https://fixit.lruihao.cn/docs/content-management/) ➜ [Advanced Usage](https://fixit.lruihao.cn/docs/advanced/)
Outline: [Installation](https://fixit.lruihao.cn/documentation/installation/) ➜ [Getting Started](https://fixit.lruihao.cn/documentation/getting-started/) ➜ [Content Management](https://fixit.lruihao.cn/documentation/content-management/) ➜ [Advanced Usage](https://fixit.lruihao.cn/documentation/advanced/)
### Starter Wizard
@@ -105,11 +105,10 @@ Click the following links to generate a new repository with template:
- **Responsive** layout
- **Light/Dark** mode
- **RTL (Right-to-Left)** layout supported
- Globally consistent **design language**
- **Pagination** supported
- Easy-to-use and self-expanding **table of contents**
- **Multilanguage** supported and I18n ready
- **Multilanguage** supported and i18n ready
- Beautiful **CSS animation**
### Social and Comment Systems
@@ -132,12 +131,12 @@ Click the following links to generate a new repository with template:
### Extended Features
- **AI Summary**, **AI Search** and **AI Chatbot** supported by [PostChat](https://ai.zhheo.com/console/login?InviteID=85041330)
- **AI Summary**, **AI Search** and **AI Chatbot** supported by [PostChat](https://ai.tianli0.top/?InviteID=IRE1S88Z)
- **PWA (Progressive Web App)** supported
- **Sub Menu** supported
- **Content Encryption** supported (Pages, Partial)
- **Friends** page embedded template
- **Search** supported by [algolia](https://www.algolia.com/), [Fuse.js](https://fusejs.io/), [Pagefind](https://pagefind.app), CSE or [PostChat](https://ai.zhheo.com/console/login?InviteID=85041330)
- **Search** supported by [algolia](https://www.algolia.com/), [Fuse.js](https://fusejs.io/), CSE or [PostChat](https://ai.tianli0.top/?InviteID=IRE1S88Z)
- **Custom Search Engine (CSE)** supported by [Google](https://programmablesearchengine.google.com/)
- **Twemoji** supported
- Automatically **highlighting** code
@@ -146,16 +145,14 @@ Click the following links to generate a new repository with template:
- Extended Markdown syntax for **[Font Awesome](https://fontawesome.com/) icons**
- Extended Markdown syntax for **ruby annotation**
- Extended Markdown syntax for **fraction**
- Multiple **admonitions** shortcode or **alerts** extended Markdown syntax
- **Tabs** and **Tab** shortcode with multiple design styles
- **Mathematical formula** supported by [KaTeX](https://katex.org/) or [MathJax](https://www.mathjax.org)
- **Mathematical formula** supported by [KaTeX](https://katex.org/)
- **Diagrams** code fences extended and shortcode supported by [mermaid](https://github.com/knsv/mermaid)
- **Interactive data visualization** shortcode and code fences extended supported by [ECharts](https://echarts.apache.org/)
- **Timeline** code fences extended and shortcode supported
- **File tree** code fences extended and shortcode supported
- **Mapbox** shortcode supported by [Mapbox GL JS](https://docs.mapbox.com/mapbox-gl-js)
- **Music player** shortcode supported by [APlayer](https://github.com/MoePlayer/APlayer) and [MetingJS](https://github.com/metowolf/MetingJS)
- **Bilibili player** and **Douyin player** shortcode
- Kinds of **admonitions** shortcode
- **Custom style** shortcode
- **Custom script** shortcode
- Open more **custom blocks**
@@ -168,9 +165,9 @@ Click the following links to generate a new repository with template:
</details>
## Multilingual and I18n
## Multilingual and i18n
FixIt supports multilingual and i18n. For more information, see the [Content Management](https://fixit.lruihao.cn/docs/content-management/introduction#multilingual) documentation. You are welcome to [contribute with a new language](https://github.com/hugo-fixit/FixIt/pulls).
FixIt supports multilingual and i18n. For more information, see the [Content Management](https://fixit.lruihao.cn/documentation/content-management/introduction#multilingual) documentation. You are welcome to [contribute with a new language](https://github.com/hugo-fixit/FixIt/pulls).
<details>
<summary>FixIt supports the following languages.</summary>
@@ -189,26 +186,12 @@ FixIt supports multilingual and i18n. For more information, see the [Content Man
- Romanian
- Vietnamese
- Hindi
- Japanese
- Korean
- Arabic
- Persian
- Urdu
</details>
## Browsers Support
The FixIt theme supports the last two versions of all major browsers.
![Chrome](https://img.shields.io/badge/Chrome-last+2-blue?logo=googlechrome)
![Edge](https://img.shields.io/badge/Edge-last+2-blue?logo=microsoft-edge)
![Firefox](https://img.shields.io/badge/Firefox-last+2-orange?logo=firefox)
![Safari](https://img.shields.io/badge/Safari-last+2-blue?logo=safari)
## Theme Components
To balance **simplicity** and **extensibility**, FixIt theme provides extra [Hugo theme components](https://fixit.lruihao.cn/ecosystem/#-components) for customization.
The FixIt theme balances **simplicity** and **extensibility** with extra [Hugo theme components](https://fixit.lruihao.cn/ecosystem/#-components) for customization.
<details>
<summary>Click to view.</summary>
@@ -217,11 +200,9 @@ To balance **simplicity** and **extensibility**, FixIt theme provides extra [Hug
- [fixit-bundle](https://github.com/hugo-fixit/fixit-bundle)\
🌲 Bundles the FixIt core theme and all hugo-fixit components into a single component.
- [cmpt-flyfish](https://github.com/hugo-fixit/cmpt-flyfish)\
🐟 A canvas implemented animation effect of small fish swimming.
🐟 一个 canvas 实现的小鱼游动动画效果。
- [cmpt-mdevtools](https://github.com/hugo-fixit/cmpt-mdevtools)\
Mobile devtools component powered by vConsole and eruda.
- [cmpt-santa-hat](https://github.com/hugo-fixit/cmpt-santa-hat)\
A Christmas Easter Egg by JavaScript.
- [cmpt-translate](https://github.com/hugo-fixit/cmpt-translate)\
🌐 A component for site automatic translation.
- [component-projects](https://github.com/hugo-fixit/component-projects)\
@@ -233,13 +214,9 @@ To balance **simplicity** and **extensibility**, FixIt theme provides extra [Hug
- [shortcode-asciinema](https://github.com/hugo-fixit/shortcode-asciinema)\
A Hugo theme component with asciinema-embed shortcode.
- [shortcode-caniuse](https://github.com/hugo-fixit/shortcode-caniuse)\
A Hugo theme component with caniuse shortcode.
一个含有 caniuse shortcode 的 Hugo 主题组件。
- [shortcode-docs-bookmark](https://github.com/hugo-fixit/shortcode-docs-bookmark)\
🔖 Embed bookmark of FixIt Docs.
- [shortcode-missing-translation](https://github.com/hugo-fixit/shortcode-missing-translation)\
A Hugo theme component with missing-translation shortcode.
- [shortcode-mmt-netease](https://github.com/hugo-fixit/shortcode-mmt-netease)\
🎶 A Hugo theme component with a NetEase Cloud random comment shortcode.
- [shortcode-rewards](https://github.com/hugo-fixit/shortcode-rewards)\
A Hugo theme component with reward-log or sponsor-log shortcode.
<!-- HUGO_FIXIT_COMPONENTS:END -->
@@ -250,23 +227,19 @@ To balance **simplicity** and **extensibility**, FixIt theme provides extra [Hug
All feedback is welcome! Head over to the [discussions][discussions], [Pull requests][pulls] and [issues][issues] tracker.
| Official Community | Description |
| :--------------------------- | :------------------------------ |
| [Discussions][discussions] | GitHub discussion forum |
| [FixIt WeChat group][wx-mp] | Follow and reply "FixIt" to get |
| [FixIt QQ group][qq-group] | QQ group: `814031017` |
| [FixIt Dev group][dev-group] | QQ group: `770835493` |
| Official Community | Description |
| :-------------------------- | :------------------------------ |
| [Discussions][discussions] | GitHub discussion forum |
| [FixIt WeChat group][wx-mp] | Follow and reply "FixIt" to get |
| [FixIt QQ group][qq-group] | QQ group: `814031017` |
| [Hugo FixIt Planet][zsxq] | Paid knowledge Planet |
[discussions]: https://github.com/hugo-fixit/FixIt/discussions
[pulls]: https://github.com/hugo-fixit/FixIt/pulls
[issues]: https://github.com/hugo-fixit/FixIt/issues
[qq-group]: https://qm.qq.com/cgi-bin/qm/qr?k=awbwdTtSQ_-H5QGzeJxdWgv6JMbNehNM&jump_from=webapi
[zsxq]: https://t.zsxq.com/GgKEW
[wx-mp]: https://lruihao.cn/images/qr-wx-mp.webp
[qq-group]: https://qm.qq.com/q/Mn1I7ljqsS
[dev-group]: https://qm.qq.com/q/ky3uru0mbu
## China Mirror
A mirror is available on Gitee for users in mainland China: [gitee.com/lruihao/FixIt](https://gitee.com/lruihao/FixIt)
## Contributing
@@ -279,19 +252,16 @@ Also, we welcome Issue or PR to our [official-components](https://github.com/hug
## Acknowledgements
Thanks to the support of [all contributors](https://github.com/hugo-fixit/FixIt/graphs/contributors)!
Thanks to the [Hugo DoIt](https://github.com/HEIGE-PCloud/DoIt) theme and [Hexo NexT](https://github.com/next-theme/hexo-theme-next) theme for inspiration and reference.
Thanks to all the [contributors](https://github.com/hugo-fixit/FixIt/graphs/contributors) for their support!
<details>
<summary>Thanks to all the open source projects used in the FixIt theme.</summary>
<summary>Thanks to the authors of following resources included in the theme:</summary>
- [UnoCSS](https://github.com/unocss/unocss)
- [normalize.css](https://github.com/necolas/normalize.css)
- [Font Awesome](https://github.com/FortAwesome/Font-Awesome)
- [Font Awesome](https://fontawesome.com/)
- [Simple Icons](https://github.com/simple-icons/simple-icons)
- [Animate.css](https://github.com/animate-css/animate.css)
- [autocomplete](https://github.com/algolia/autocomplete)
- [Animate.css](https://daneden.github.io/animate.css/)
- [autocomplete-js](https://github.com/algolia/autocomplete)
- [algoliasearch](https://github.com/algolia/algoliasearch-client-javascript)
- [Fuse.js](https://fusejs.io/)
- [object-fit-images](https://github.com/fregante/object-fit-images)
@@ -301,7 +271,6 @@ Thanks to the [Hugo DoIt](https://github.com/HEIGE-PCloud/DoIt) theme and [Hexo
- [Sharer.js](https://github.com/ellisonleao/sharer.js)
- [TypeIt](https://typeitjs.com/)
- [KaTeX](https://katex.org/)
- [MathJax](https://www.mathjax.org)
- [mermaid](https://github.com/mermaid-js/mermaid)
- [ECharts](https://echarts.apache.org/)
- [Mapbox GL JS](https://docs.mapbox.com/mapbox-gl-js)
@@ -318,10 +287,18 @@ Thanks to the [Hugo DoIt](https://github.com/HEIGE-PCloud/DoIt) theme and [Hexo
- [Waline](https://waline.js.org/)
- [Twikoo](https://twikoo.js.org/)
- [github-corners](https://github.com/tholman/github-corners)
- [giscus](https://giscus.app/zh-CN)
- [giscus](https://giscus.app/)
- [crypto-js](https://github.com/brix/crypto-js)
- [pace](https://github.com/CodeByZach/pace)
- [`<tab-container>` element](https://github.com/github/tab-container-element)
- [`<json-viewer>` element](https://github.com/Lruihao/json-viewer-element)
- [xxhash-wasm](https://github.com/jungomi/xxhash-wasm)
</details>
<details>
<summary>The FixIt also draws on some features of the following projects, and thanks to their authors as well:</summary>
- [DoIt](https://github.com/HEIGE-PCloud/DoIt)
- [NexT](https://github.com/next-theme/hexo-theme-next)
</details>
@@ -329,17 +306,17 @@ Thanks to the [Hugo DoIt](https://github.com/HEIGE-PCloud/DoIt) theme and [Hexo
FixIt is licensed under the **MIT** license. Check the [LICENSE file](/LICENSE) for details.
## Sponsor Support
## Sponsor
If you enjoy the theme, please consider buying me a cup of coffee ☕️. Thanks!
If you enjoy the theme, please consider buying me a coffee ☕️. Thanks!
- [WeChat Pay](/images/wechatpay.jpg)
- [Wechat](/images/wechatpay.jpg)
- [Alipay](/images/alipay.jpg)
<!-- - [PayPal](https://paypal.me/Lruihao) -->
- [PayPal](https://paypal.me/Lruihao)
Thanks to the following sponsors for their great support:
Thanks to the following sponsors for their support:
- [translate.js](https://github.com/xnx3/translate) sponsored [Enterprise Translation Channel](https://translate.zvo.cn/4087.html).
- [translate.js](https://github.com/xnx3/translate) Sponsoring [Enterprise Translation Channel](https://translate.zvo.cn/4087.html).
## Author
+75 -94
View File
@@ -13,9 +13,9 @@
<a href="https://fixit.lruihao.cn/ecosystem/hugo-fixit/fixit/?lang=russian">Русский язык</a> |
<a href="https://fixit.lruihao.cn/ecosystem/hugo-fixit/fixit/?lang=spanish">Español</a> |
<a href="https://fixit.lruihao.cn/ecosystem/hugo-fixit/fixit/?lang=hindi">हिन्दी</a> |
<a href="https://fixit.lruihao.cn/ecosystem/hugo-fixit/fixit/?lang=deutsch">Deutsch</a> |
<a href="https://fixit.lruihao.cn/ecosystem/hugo-fixit/fixit/?lang=german">deutsch</a> |
<a href="https://fixit.lruihao.cn/ecosystem/hugo-fixit/fixit/?lang=korean">한국어</a> |
<a href="https://fixit.lruihao.cn/ecosystem/hugo-fixit/fixit/?lang=japanese">日本語</a>
<a href="https://fixit.lruihao.cn/ecosystem/hugo-fixit/fixit/?lang=japanese">しろうと</a>
</div>
<a title="FixIt 官网" href="https://fixit.lruihao.cn/zh-cn/"><img align="right" alt="FixIt logo" width="70" height="70" src="https://avatars.githubusercontent.com/u/110414864?s=200&v=4"></a>
@@ -24,33 +24,33 @@
> 它的原型基于 [LoveIt](https://github.com/dillonzq/LoveIt) 主题,[KeepIt](https://github.com/Fastbyte01/KeepIt) 主题和 [LeaveIt](https://github.com/liuzc/LeaveIt) 主题。
[![Build](https://img.shields.io/github/deployments/hugo-fixit/FixIt/Production?style=flat&label=Build&logo=vercel)](https://demo.fixit.lruihao.cn/)
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/hugo-fixit/FixIt?style=flat&label=Release&logo=github&include_prereleases)](https://github.com/hugo-fixit/FixIt/releases)
[![Hugo](https://img.shields.io/badge/Hugo-%5E0.161.0-ff4088?style=flat&logo=hugo)](https://gohugo.io/)
[![License](https://img.shields.io/github/license/hugo-fixit/FixIt?style=flat&label=License)](/LICENSE)
[![GitHub stars](https://img.shields.io/github/stars/hugo-fixit/FixIt?style=social)](https://github.com/hugo-fixit/FixIt)
[![Gitee star of FixIt](https://gitee.com/lruihao/FixIt/badge/star.svg)](https://gitee.com/lruihao/FixIt/stargazers)
> [!WARNING]
> **当前 `main` 分支包含 v1 代码,升级详见 [v1 升级指南](https://fixit.lruihao.cn/guides/upgrade-to-v1/)**。\
> 1.0 版本计划在 **2027 年上半年** 发布,欢迎加入开发和 [讨论](https://github.com/orgs/hugo-fixit/discussions/723)
[![GitHub release (latest by date)](https://img.shields.io/github/v/release/hugo-fixit/FixIt?style=flat)](https://github.com/hugo-fixit/FixIt/releases)
[![Hugo](https://img.shields.io/badge/Hugo-%5E0.141.0-ff4088?style=flat&logo=hugo)](https://gohugo.io/)
[![License](https://img.shields.io/github/license/hugo-fixit/FixIt?style=flat)](/LICENSE)
[![Open Source Love](https://badges.frapsoft.com/os/v1/open-source.svg?v=103)](https://github.com/hugo-fixit/FixIt)
## 即时预览
<p align="center">
💟 <a href="https://fixit.lruihao.cn">Docs</a> | ❇️ <a href="https://demo.fixit.lruihao.cn/test/">Test</a> | 🚼 <a href="https://demo.fixit.lruihao.cn">Demo</a> | 🆕 <a href="https://hugo-fixit.github.io/hugo-fixit-starter/">Starter</a>
💟 <a href="https://fixit.lruihao.cn/zh-cn/">Production</a> | ❇️ <a href="https://pre.fixit.lruihao.cn/zh-cn/">Preview</a> | 🚼 <a href="https://demo.fixit.lruihao.cn">Demo</a> | 🆕 <a href="https://hugo-fixit.github.io/hugo-fixit-starter/">Starter</a>
<br>
<br>
更多 FixIt 的例子参见 <a href="https://fixit.lruihao.cn/zh-cn/showcase/">这里</a>。
</p>
## 为什么选择 FixIt
我也不知道为什么 🤷。
<!-- 懒的写…… -->
## 使用指南
### 主题文档
前往 [快速上手](https://fixit.lruihao.cn/zh-cn/docs/getting-started/quick-start/) 页面,了解如何使用 FixIt 主题创建一个新网站的详细步骤。
前往 [快速上手](https://fixit.lruihao.cn/zh-cn/documentation/getting-started/quick-start/) 页面,了解如何使用 FixIt 主题创建一个新网站的详细步骤。
大纲:[安装篇](https://fixit.lruihao.cn/zh-cn/docs/installation/) ➜ [入门篇](https://fixit.lruihao.cn/zh-cn/docs/getting-started/) ➜ [内容管理](https://fixit.lruihao.cn/zh-cn/docs/content-management/) ➜ [进阶篇](https://fixit.lruihao.cn/zh-cn/docs/advanced/)
大纲:[安装篇](https://fixit.lruihao.cn/zh-cn/documentation/installation/) ➜ [入门篇](https://fixit.lruihao.cn/zh-cn/documentation/getting-started/) ➜ [内容管理](https://fixit.lruihao.cn/zh-cn/documentation/content-management/) ➜ [进阶篇](https://fixit.lruihao.cn/zh-cn/documentation/advanced/)
### 快速开始
@@ -82,6 +82,10 @@ pnpx fixit-cli create my-blog
[lruihao-blog]: https://github.com/Lruihao/hugo-blog
[lruihao-blog:generate]: https://github.com/Lruihao/hugo-blog/generate
### 镜像
Gitee 镜像仓库:<https://gitee.com/lruihao/FixIt>
## 特色
<details>
@@ -89,8 +93,8 @@ pnpx fixit-cli create my-blog
### 性能和 SEO
- **性能优化**:在 [Google PageSpeed Insights](https://developers.google.com/speed/pagespeed/insights) 中,99/100 的移动设备得分和 100/100 的桌面设备得分
- 使用基于 JSON-LD 格式的 **SEO SCHEMA** 文件进行 SEO 优化
- **性能**优化:在 [Google PageSpeed Insights](https://developers.google.com/speed/pagespeed/insights) 中,99/100 的移动设备得分和 100/100 的桌面设备得分
- 使用基于 JSON-LD 格式 **SEO SCHEMA** 文件进行 SEO 优化
- 支持 **[Google Analytics](https://analytics.google.com/analytics)**
- 支持 **[Fathom Analytics](https://usefathom.com/)**
- 支持 **[百度统计](https://tongji.baidu.com/)**
@@ -98,24 +102,23 @@ pnpx fixit-cli create my-blog
- 支持 **[Plausible Analytics](https://plausible.io/)**
- 支持 **[Cloudflare Web Analytics](https://www.cloudflare.com/web-analytics)**
- 支持 **[Splitbee Analytics](https://splitbee.io)**
- 支持搜索引擎的 **网站验证** (Google, Bing, Yandex, Pinterest, Baidu, 360 and Sogou)
- 支持搜索引擎的**网站验证** (Google, Bing, Yandex, Pinterest, Baidu, 360 and Sogou)
- 支持所有第三方库的 **CDN**
### 外观和布局
- **响应式** 布局
- **响应式**布局
- **浅色/深色** 主题模式
- 支持 **RTL(从右到左)** 布局
- 全局一致的 **设计语言**
- 支持 **分页**
- 易用和自动展开的 **文章目录**
- 支持 **多语言** 和国际化
- 全局一致的**设计语言**
- 支持**分页**
- 易用和自动展开的**文章目录**
- 支持**多语言**和国际化
- 美观的 **CSS 动画**
### 社交和评论系统
- 支持 **[Gravatar](https://gravatar.com)** 头像
- 支持本地 **头像**
- 支持本地**头像**
- 支持多达 **87** 种社交链接
- 支持多达 **28** 种网站分享
- 支持 **[Disqus](https://disqus.com)** 评论系统
@@ -132,45 +135,43 @@ pnpx fixit-cli create my-blog
### 扩展功能
- 支持基于 [PostChat](https://ai.zhheo.com/console/login?InviteID=85041330) 的 **AI 摘要**、**AI 搜索** 和 **AI 智能客服**
- 支持 **渐进式网页应用**
- 支持 **二级菜单**
- 支持 **内容加密**(页面、局部)
- 支持 **友情链接** 的页面模板
- 支持基于 [algolia](https://www.algolia.com/)、[Fuse.js](https://fusejs.io/)、[Pagefind](https://pagefind.app)、CSE 或 [PostChat](https://ai.zhheo.com/console/login?InviteID=85041330) 的 **搜索**
- 支持基于 [Google](https://programmablesearchengine.google.com/) 的 **自定义搜索引擎 (CSE)**
- 支持基于 [PostChat](https://ai.tianli0.top/?InviteID=IRE1S88Z) 的 **AI 摘要**、**AI 搜索** 和 **AI 智能客服**
- 支持**渐进式网页应用**
- 支持**二级菜单**
- 支持**内容加密**(页面、局部)
- 支持**友情链接**的页面模板
- 支持基于 [algolia](https://www.algolia.com/)、[Fuse.js](https://fusejs.io/)、 **CSE** 或 [PostChat](https://ai.tianli0.top/?InviteID=IRE1S88Z) 的**搜索**
- 支持基于 [Google](https://programmablesearchengine.google.com/) 的**自定义搜索引擎 (CSE)**
- 支持 **Twemoji**
- 支持 **代码高亮**
- 一键 **复制代码** 到剪贴板
- 支持基于 [lightgallery](https://github.com/sachinchoolur/lightgallery) 的 **图片画廊**
- 支持 **[Font Awesome](https://fontawesome.com/) 图标** 的 Markdown 扩展语法
- 支持 **上标注释** Markdown 扩展语法
- 支持 **分数** Markdown 扩展语法
- 支持多种 **admonitions** shortcode 或 **alerts** 的 Markdown 扩展语法
- 支持 **标签页** shortcode,提供多种设计样式
- 支持基于 [KaTeX](https://katex.org/) 或 [MathJax](https://www.mathjax.org) 的 **数学公式**
- 支持基于 [mermaid](https://github.com/knsv/mermaid) 的 **图表** 代码块扩展语法和 shortcode
- 支持基于 [ECharts](https://echarts.apache.org/) 的 **交互式数据可视化** 代码块扩展语法和 shortcode
- 支持**代码高亮**
- 一键**复制代码**到剪贴板
- 支持基于 [lightgallery](https://github.com/sachinchoolur/lightgallery) 的**图片画廊**
- 支持 **[Font Awesome](https://fontawesome.com/) 图标**的扩展 Markdown 语法
- 支持**上标注释**的扩展 Markdown 语法
- 支持**分数**的扩展 Markdown 语法
- 支持基于 [KaTeX](https://katex.org/) 的**数学公式**
- 支持基于 [mermaid](https://github.com/knsv/mermaid) 的**图表** 代码块扩展语法和 shortcode
- 支持基于 [ECharts](https://echarts.apache.org/) 的**交互式数据可视化** 代码块扩展语法和 shortcode
- 支持 **Timeline** 的代码块扩展语法和 shortcode
- 支持 **文件树** 的代码块扩展语法和 shortcode
- 支持基于 [Mapbox GL JS](https://docs.mapbox.com/mapbox-gl-js) 的 **Mapbox** shortcode
- 支持基于 [APlayer](https://github.com/MoePlayer/APlayer) 和 [MetingJS](https://github.com/metowolf/MetingJS) 的 **音乐播放器** shortcode
- 支持基于 [APlayer](https://github.com/MoePlayer/APlayer) 和 [MetingJS](https://github.com/metowolf/MetingJS) 的**音乐播放器** shortcode
- 支持 **Bilibili 视频****抖音视频** shortcode
- 支持 **自定义样式** 的 shortcode
- 支持 **自定义脚本** 的 shortcode
- 支持 **自定义模板块**
- 支持多种**注释**的 shortcode
- 支持**自定义样式**的 shortcode
- 支持**自定义脚本**的 shortcode
- 支持**自定义模板块**
- 支持基于 [TypeIt](https://typeitjs.com/) 的**打字动画** shortcode
- 支持基于 [cookieconsent](https://github.com/osano/cookieconsent) 的 **Cookie 许可横幅**
- 支持基于 [cell-watermark](https://github.com/Lruihao/watermark) 的 **网页水印**
- 支持基于 [pangu.js](https://github.com/vinta/pangu.js) 的 **中文排版**
- 支持本地 **缓存远程图床图片**
- 支持基于 [cell-watermark](https://github.com/Lruihao/watermark) 的**网页水印**
- 支持基于 [pangu.js](https://github.com/vinta/pangu.js) 的**中文排版**
- 支持本地**缓存远程图床图片**
- ……
</details>
## 多语言和国际化
FixIt 主题多语言基本配置及自动翻译等详见 [内容管理](https://fixit.lruihao.cn/zh-cn/docs/content-management/introduction#multilingual) 文档,欢迎 [贡献一种新的语言](https://github.com/hugo-fixit/FixIt/pulls)。
FixIt 主题多语言基本配置及自动翻译等详见 [内容管理](https://fixit.lruihao.cn/zh-cn/documentation/content-management/introduction#multilingual) 文档,欢迎 [贡献一种新的语言](https://github.com/hugo-fixit/FixIt/pulls)。
<details>
<summary>FixIt 支持下列语言。</summary>
@@ -189,26 +190,12 @@ FixIt 主题多语言基本配置及自动翻译等详见 [内容管理](https:/
- 罗马尼亚语
- 越南语
- 印地语
- 日语
- 韩语
- 阿拉伯语
- 波斯语
- 乌尔都语
</details>
## 浏览器支持
FixIt 主题支持所有主流浏览器的最近两个版本。
![Chrome](https://img.shields.io/badge/Chrome-last+2-blue?logo=googlechrome)
![Edge](https://img.shields.io/badge/Edge-last+2-blue?logo=microsoft-edge)
![Firefox](https://img.shields.io/badge/Firefox-last+2-orange?logo=firefox)
![Safari](https://img.shields.io/badge/Safari-last+2-blue?logo=safari)
## 主题组件
为了平衡 FixIt 主题**简洁性****可扩展性**,我们额外开发了一系列 [Hugo 主题组件](https://fixit.lruihao.cn/zh-cn/ecosystem/#-组件) 供用户选择。
FixIt 主题旨在在**简洁性**和**可扩展性**之间取得平衡。为此,我们开发了一系列额外的 [Hugo 主题组件](https://fixit.lruihao.cn/zh-cn/ecosystem/#-组件) 供用户选择。
<details>
<summary>点击展开</summary>
@@ -217,11 +204,9 @@ FixIt 主题支持所有主流浏览器的最近两个版本。
- [fixit-bundle](https://github.com/hugo-fixit/fixit-bundle)\
🌲 Bundles the FixIt core theme and all hugo-fixit components into a single component.
- [cmpt-flyfish](https://github.com/hugo-fixit/cmpt-flyfish)\
🐟 A canvas implemented animation effect of small fish swimming.
🐟 一个 canvas 实现的小鱼游动动画效果。
- [cmpt-mdevtools](https://github.com/hugo-fixit/cmpt-mdevtools)\
Mobile devtools component powered by vConsole and eruda.
- [cmpt-santa-hat](https://github.com/hugo-fixit/cmpt-santa-hat)\
A Christmas Easter Egg by JavaScript.
- [cmpt-translate](https://github.com/hugo-fixit/cmpt-translate)\
🌐 A component for site automatic translation.
- [component-projects](https://github.com/hugo-fixit/component-projects)\
@@ -233,13 +218,9 @@ FixIt 主题支持所有主流浏览器的最近两个版本。
- [shortcode-asciinema](https://github.com/hugo-fixit/shortcode-asciinema)\
A Hugo theme component with asciinema-embed shortcode.
- [shortcode-caniuse](https://github.com/hugo-fixit/shortcode-caniuse)\
A Hugo theme component with caniuse shortcode.
一个含有 caniuse shortcode 的 Hugo 主题组件。
- [shortcode-docs-bookmark](https://github.com/hugo-fixit/shortcode-docs-bookmark)\
🔖 Embed bookmark of FixIt Docs.
- [shortcode-missing-translation](https://github.com/hugo-fixit/shortcode-missing-translation)\
A Hugo theme component with missing-translation shortcode.
- [shortcode-mmt-netease](https://github.com/hugo-fixit/shortcode-mmt-netease)\
🎶 A Hugo theme component with a NetEase Cloud random comment shortcode.
- [shortcode-rewards](https://github.com/hugo-fixit/shortcode-rewards)\
A Hugo theme component with reward-log or sponsor-log shortcode.
<!-- HUGO_FIXIT_COMPONENTS:END -->
@@ -255,18 +236,14 @@ FixIt 主题支持所有主流浏览器的最近两个版本。
| [Discussions][discussions] | GitHub 讨论区 |
| [FixIt 主题交流群(微信)][wx-mp] | 关注「菠菜眾長」回复“FixIt”获取 |
| [FixIt 主题交流群(QQ][qq-group] | QQ 群:`814031017` |
| [FixIt 开发交流群][dev-group] | QQ 群:`770835493` |
| [Hugo FixIt 星球][zsxq] | 付费知识星球 |
[discussions]: https://github.com/hugo-fixit/FixIt/discussions
[pulls]: https://github.com/hugo-fixit/FixIt/pulls
[issues]: https://github.com/hugo-fixit/FixIt/issues
[qq-group]: https://qm.qq.com/cgi-bin/qm/qr?k=awbwdTtSQ_-H5QGzeJxdWgv6JMbNehNM&jump_from=webapi
[zsxq]: https://t.zsxq.com/GgKEW
[wx-mp]: https://lruihao.cn/images/qr-wx-mp.webp
[qq-group]: https://qm.qq.com/q/Mn1I7ljqsS
[dev-group]: https://qm.qq.com/q/ky3uru0mbu
## 中国区镜像
为方便中国大陆用户访问,FixIt 在 Gitee 上提供了镜像仓库:[gitee.com/lruihao/FixIt](https://gitee.com/lruihao/FixIt)
## 参与贡献
@@ -281,17 +258,14 @@ FixIt 主题支持所有主流浏览器的最近两个版本。
感谢 [所有贡献者](https://github.com/hugo-fixit/FixIt/graphs/contributors) 的支持!
感谢 [Hugo DoIt](https://github.com/HEIGE-PCloud/DoIt) 主题和 [Hexo NexT](https://github.com/next-theme/hexo-theme-next) 主题给予的灵感和借鉴。
<details>
<summary>感谢 FixIt 主题中使用的所有开源项目。</summary>
<summary>FixIt 主题中用到了以下项目,感谢它们的作者:</summary>
- [UnoCSS](https://github.com/unocss/unocss)
- [normalize.css](https://github.com/necolas/normalize.css)
- [Font Awesome](https://github.com/FortAwesome/Font-Awesome)
- [Font Awesome](https://fontawesome.com/)
- [Simple Icons](https://github.com/simple-icons/simple-icons)
- [Animate.css](https://github.com/animate-css/animate.css)
- [autocomplete](https://github.com/algolia/autocomplete)
- [Animate.css](https://daneden.github.io/animate.css/)
- [autocomplete-js](https://github.com/algolia/autocomplete)
- [algoliasearch](https://github.com/algolia/algoliasearch-client-javascript)
- [Fuse.js](https://fusejs.io/)
- [object-fit-images](https://github.com/fregante/object-fit-images)
@@ -301,7 +275,6 @@ FixIt 主题支持所有主流浏览器的最近两个版本。
- [Sharer.js](https://github.com/ellisonleao/sharer.js)
- [TypeIt](https://typeitjs.com/)
- [KaTeX](https://katex.org/)
- [MathJax](https://www.mathjax.org)
- [mermaid](https://github.com/mermaid-js/mermaid)
- [ECharts](https://echarts.apache.org/)
- [Mapbox GL JS](https://docs.mapbox.com/mapbox-gl-js)
@@ -319,9 +292,17 @@ FixIt 主题支持所有主流浏览器的最近两个版本。
- [Twikoo](https://twikoo.js.org/)
- [github-corners](https://github.com/tholman/github-corners)
- [giscus](https://giscus.app/zh-CN)
- [crypto-js](https://github.com/brix/crypto-js)
- [pace](https://github.com/CodeByZach/pace)
- [`<tab-container>` element](https://github.com/github/tab-container-element)
- [`<json-viewer>` element](https://github.com/Lruihao/json-viewer-element)
- [xxhash-wasm](https://github.com/jungomi/xxhash-wasm)
</details>
<details>
<summary>FixIt 主题还借鉴了以下项目的部分功能,同样感谢它们的作者:</summary>
- [DoIt](https://github.com/HEIGE-PCloud/DoIt)
- [NexT](https://github.com/next-theme/hexo-theme-next)
</details>
@@ -335,11 +316,11 @@ FixIt 根据 **MIT** 许可协议授权。更多信息请查看 [LICENSE 文件]
- [微信支付](/images/wechatpay.jpg)
- [支付宝](/images/alipay.jpg)
<!-- - [PayPal](https://paypal.me/Lruihao) -->
- [PayPal](https://paypal.me/Lruihao)
感谢以下赞助商提供大力支持:
- [translate.js](https://github.com/xnx3/translate) 赞助 [企业级翻译通道](https://translate.zvo.cn/4087.html)。
- [translate.js](https://github.com/xnx3/translate) 赞助[企业级翻译通道](https://translate.zvo.cn/4087.html)。
## 作者
+9 -65
View File
@@ -2,73 +2,17 @@
## Supported Versions
Only the latest version receives active maintenance and security updates:
| Version | Supported |
| :-----------: | :----------------: |
| 0.3.x | :white_check_mark: |
| Version | Hugo Version | LoveIt Compat | Supported |
| :-----: | :---------------: | :----------------: | :----------------: |
| 1.x | 0.159.0 ~ latest | N/A | :white_check_mark: |
| 0.4.x | 0.147.7 ~ 0.157.0 | N/A | :white_check_mark: |
| 0.3.x | 0.112.0 ~ 0.146.0 | N/A | :x: |
| 0.2.x | 0.62.0 ~ 0.110.0 | :white_check_mark: | :x: |
| 0.1.x | Unknown | :white_check_mark: | :x: |
legacy and transitional versions:
## Security Considerations
### Theme Security Features
- **Content Security Policy (CSP)** support
- **Subresource Integrity (SRI)** for external resources
- **XSS protection** through Hugo's built-in escaping
- **Safe HTML rendering** with configurable markup
- **Secure defaults** for all theme configurations
### Best Practices
1. **Keep Hugo Updated**: Always use the latest stable Hugo version
2. **Regular Updates**: Update the theme regularly to get security patches
3. **Content Validation**: Validate user-generated content before publishing
4. **HTTPS Only**: Always deploy sites with HTTPS enabled
### Known Security Considerations
- External CDN resources should be reviewed before enabling
- User-generated content requires proper sanitization
- Third-party integrations (comments, analytics) should be configured securely
| Version | Supported | LoveIt Compatibility |
| :-----------: | :----------------: | :------------------: |
| 0.1.x | :x: | :white_check_mark: |
| 0.2.x | :x: | :white_check_mark: |
## Reporting a Vulnerability
We take security seriously and appreciate your help in keeping FixIt secure.
### How to Report
1. **Create an Issue**: Report vulnerabilities at https://github.com/hugo-fixit/FixIt/issues
2. **Private Disclosure**: For sensitive security issues, email the maintainers directly
3. **Include Details**: Provide clear steps to reproduce the vulnerability
### What to Include
- **Description**: Clear description of the vulnerability
- **Impact**: Potential impact and severity
- **Reproduction**: Step-by-step instructions to reproduce
- **Environment**: Hugo version, theme version, and platform details
- **Solution**: Suggested fix if you have one
### Response Timeline
- **Acknowledgment**: Within 48 hours
- **Initial Assessment**: Within 1 week
- **Status Updates**: Weekly updates on progress
- **Resolution**: Security fixes are prioritized and released as soon as possible
### Disclosure Policy
- We follow responsible disclosure practices
- We will coordinate with you on the disclosure timeline
## Security Resources
- [Hugo Security Model](https://gohugo.io/about/security/)
- [OWASP Web Security Testing Guide](https://owasp.org/www-project-web-security-testing-guide/)
- [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP)
<!-- This security policy was enhanced and generated with assistance from GitHub Copilot AI -->
If you want to report a vulnerability, create a new issue at https://github.com/hugo-fixit/FixIt/issues. Any vulnerabilities will be fixed as soon as possible.
-25
View File
@@ -1,25 +0,0 @@
# Apps
This directory contains the Hugo sites used for development, testing, and demonstration of the [FixIt](https://fixit.lruihao.cn) theme.
## Overview
| App | Description | Live |
| -------------- | ----------------------------------------------------- | ----------------------------------------------------------------- |
| [demo](./demo) | Demo site showcasing FixIt theme features | [demo.fixit.lruihao.cn](https://demo.fixit.lruihao.cn) |
| [test](./test) | Test site for exercising and verifying theme features | [demo.fixit.lruihao.cn/test](https://demo.fixit.lruihao.cn/test/) |
> [!NOTE]
> The documentation site (`fixit-docs`) lives in a separate repository: [hugo-fixit/fixit-docs](https://github.com/hugo-fixit/fixit-docs).
## Development
From the repository root:
```bash
pnpm dev:demo # Start demo site dev server
pnpm dev:test # Start test site dev server
pnpm build:demo # Build demo site
pnpm build:test # Build test site
pnpm build # Build all sites (merged into public/)
```
-8
View File
@@ -1,8 +0,0 @@
{
"name": "@hugo-fixit/demo",
"private": true,
"scripts": {
"build": "hugo --themesDir ../.. --theme . --gc --minify --logLevel info",
"dev": "hugo server --themesDir ../.. --theme . -D --disableFastRender --navigateToChanged --ignoreCache -O"
}
}
-72
View File
@@ -1,72 +0,0 @@
[
{
"name": "src-json",
"type": "dir",
"children": [
{
"name": "index.ts",
"type": "file"
},
{
"name": "components",
"type": "dir",
"children": [
{
"name": "Header.tsx",
"type": "file"
},
{
"name": "Footer.tsx",
"type": "file"
}
]
},
{
"name": "utils",
"type": "dir",
"children": [
{
"name": "helper.ts",
"type": "file"
},
{
"name": "validator.ts",
"type": "file"
}
]
}
]
},
{
"name": "public",
"type": "dir",
"children": [
{
"name": "favicon.ico",
"type": "file"
},
{
"name": "images",
"type": "dir",
"children": [
{
"name": "logo.png",
"type": "file"
}
]
}
]
},
{
"name": "package.json",
"type": "file"
},
{
"name": "README.md",
"type": "file"
},
{
"name": "tsconfig.json",
"type": "file"
}
]
Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

-4
View File
@@ -1,4 +0,0 @@
---
title: All Tests
titleIcon: fa-solid fa-flask
---
@@ -1,165 +0,0 @@
---
title: Alerts and Admonition Syntax Test
date: 2025-09-05T16:57:58+08:00
collections:
- Tests
categories:
- Markdown
- Shortcodes
tags:
- Alerts
- Admonition
---
This article comprehensively tests the **Alerts** Markdown syntax extension and **Admonition** shortcode functionality in the FixIt theme.
<!--more-->
## Basic Alerts Syntax
> [!NOTE]
> Highlights information that users should take into account, even when skimming.
> [!TIP]
> Optional information to help a user be more successful.
> [!IMPORTANT]
> Crucial information necessary for users to succeed.
> [!WARNING]
> Critical content demanding immediate user attention due to potential risks.
> [!CAUTION]
> Negative potential consequences of an action.
## Extended Alerts Syntax
### Custom Titles
> [!NOTE] FixIt
> A clean, elegant but advanced Hugo theme.
> [!TIP] This is a title-only alert.
### Foldable Alerts
Create foldable alerts by adding a plus (+) or minus (-) directly after the type identifier:
> [!WARNING]+ Radiation Hazard
> Do not approach or handle without protective gear.
> [!QUESTION]- Are alerts foldable?
> Yes! In a foldable alert, the contents are hidden when collapsed.
### Nested Alerts
Alerts can be nested in multiple levels:
> [!question] Can alerts be nested?
> > [!todo] Yes! They can be nested.
> > > [!example] You can even use multiple layers of nesting.
### Content-only Alerts
> [!TIP]~
> This is a content-only alert without a title.
### Supported types
> [!note]+
> This is a note type alert example.
> [!abstract]-
> This is an abstract type alert example. Aliases: `summary`, `tldr`
> [!info]-
> This is an info type alert example.
> [!todo]-
> This is a todo type alert example.
> [!tip]-
> This is a tip type alert example. Aliases: `hint`, `important`
> [!success]-
> This is a success type alert example. Aliases: `check`, `done`
> [!question]-
> This is a question type alert example. Aliases: `help`, `faq`
> [!warning]-
> This is a warning type alert example. Aliases: `caution`, `attention`
> [!failure]-
> This is a failure type alert example. Aliases: `fail`, `missing`
> [!danger]-
> This is a danger type alert example. Aliases: `error`
> [!bug]-
> This is a bug type alert example.
> [!example]-
> This is an example type alert example.
> [!quote]-
> This is a quote type alert example. Aliases: `cite`
## Admonition Shortcode
{{< admonition >}}
This is the default note type admonition.
{{< /admonition >}}
{{< admonition abstract "" false >}}
This is the default abstract type admonition. Aliases: `summary`, `tldr`
{{< /admonition >}}
{{< admonition info "" false >}}
This is the default info type admonition.
{{< /admonition >}}
{{< admonition todo "" false >}}
This is the default todo type admonition.
{{< /admonition >}}
{{< admonition tip "" false >}}
This is the default tip type admonition. Aliases: `hint`, `important`
{{< /admonition >}}
{{< admonition success "" false >}}
This is the default success type admonition. Aliases: `check`, `done`
{{< /admonition >}}
{{< admonition question "" false >}}
This is the default question type admonition. Aliases: `help`, `faq`
{{< /admonition >}}
{{< admonition warning "" false >}}
This is the default warning type admonition. Aliases: `caution`, `attention`
{{< /admonition >}}
{{< admonition failure "" false >}}
This is the default failure type admonition. Aliases: `fail`, `missing`
{{< /admonition >}}
{{< admonition danger "" false >}}
This is the default danger type admonition. Aliases: `error`
{{< /admonition >}}
{{< admonition bug "" false >}}
This is the default bug type admonition.
{{< /admonition >}}
{{< admonition example "" false >}}
This is the default example type admonition.
{{< /admonition >}}
{{< admonition quote "" false >}}
This is the default quote type admonition. Aliases: `cite`
{{< /admonition >}}
## Special Types
> [!center]
> This paragraph is **center-aligned**.
@@ -1,3 +0,0 @@
[00:00.00]APlayer audio1
[00:04.01]is
[00:08.02]amazing
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

@@ -1,34 +0,0 @@
---
title: APlayer Test
date: 2025-10-21T11:00:04+08:00
collections:
- Tests
categories:
- Shortcodes
tags:
- APlayer
---
Testing APlayer shortcode in FixIt theme.
<!--more-->
{{< aplayer fixed=false mini=false autoplay=false theme="#b7daff" loop="all" order="list" preload="auto" volume=0.7 mutex=true lrcType=3 listFolded=false listMaxHeight="" storageName="aplayer-setting" >}}
{{< audio name="Wavelength1" artist="oldmanyoung1" url="Wavelength.mp3" cover="Wavelength.webp" lrc="Wavelength.lrc" />}}
{{< audio name="Wavelength2" artist="oldmanyoung2" url="Wavelength.mp3" cover="Wavelength.webp" />}}
{{< /aplayer >}}
{{< aplayer fixed=false mini=false autoplay=false theme="#b7daff" loop="all" order="list" preload="auto" volume=0.7 mutex=true lrcType=1 listFolded=false listMaxHeight="" storageName="aplayer-setting" >}}
{{< audio name="Wavelength1" artist="oldmanyoung1" url="Wavelength.mp3" cover="Wavelength.webp" />}}
{{< audio name="Wavelength2" artist="oldmanyoung2" url="Wavelength.mp3" cover="Wavelength.webp" >}}
[00:00.00]APlayer audio2
[00:04.01]is
[00:08.02]amazing
{{< /audio >}}
{{< /aplayer >}}
{{% fixit-encryptor "1212" %}}
{{< aplayer fixed=false mini=false autoplay=false theme="#b7daff" loop="all" order="list" preload="auto" volume=0.7 mutex=true lrcType=3 listFolded=false listMaxHeight="" storageName="aplayer-setting" >}}
{{< audio name="Wavelength" artist="oldmanyoung" url="Wavelength.mp3" cover="Wavelength.webp" lrc="Wavelength.lrc" />}}
{{< /aplayer >}}
{{% /fixit-encryptor %}}
-166
View File
@@ -1,166 +0,0 @@
---
title: Code Tabs Test
date: 2026-01-25T07:50:22+08:00
collections:
- Tests
categories:
- Markdown
tags:
- Code Tabs
---
Code tabs test cases for grouped code blocks.
<!--more-->
## Default Name
```python {group=tab2}
print("Python")
```
```go {group=tab2}
fmt.Println("Go")
```
## Custom Name
```js {group=tab-actions name="[JavaScript]"}
function sum(a, b) {
return a + b
}
console.log(sum(1, 2))
```
```python {group=tab-actions name="[Python]"}
def sum(a, b):
return a + b
print(sum(1, 2))
```
## Active Tab
```js {group=tab-active name="Inactive Tab"}
function greet(name) {
return `Hello, ${name}!`
}
```
```python {group=tab-active name="Active Tab" .active}
def greet(name):
return f"Hello, {name}!"
```
## Shadow
```js {group=tab-shadow name="Always" shadow="always"}
function greet(name) {
return `Hello, ${name}!`
}
```
```python {group=tab-shadow name="Hover" shadow="hover"}
def greet(name):
return f"Hello, {name}!"
```
```go {group=tab-shadow name="Never" shadow="never"}
func greet(name string) string {
return fmt.Sprintf("Hello, %s!", name)
}
```
## Mode
```ts {group=tab-mode name="Classic"}
interface User {
id: number
name: string
}
```
```ts {group=tab-mode name="Mac" mode="mac"}
interface User {
id: number
name: string
}
```
```ts {group=tab-mode name="Simple" mode="simple"}
interface User {
id: number
name: string
}
```
## Actions
```bash {group=tab-actions name="lineNos=true" lineNos=true}
echo "line 1"
echo "line 2"
echo "line 3"
```
```bash {group=tab-actions name="lineNos=false" lineNos=false}
echo "line 1"
echo "line 2"
echo "line 3"
```
```bash {group=tab-actions name="wrapping" .line-wrapping}
printf "this is a very very very very very very very very very very very very very very very very long line"
```
```js {group=tab-actions name="editable" editable=true}
function greet(name) {
return `Hello, ${name}!`
}
```
## Expanded/Collapsed
```js {group=tab-expand name="Expanded"}
function longFunction() {
console.log('This is a long function.')
console.log('It has many lines of code.')
console.log('The code block should be expanded by default.')
console.log('Lorem ipsum dolor sit amet, consectetur adipiscing elit.')
console.log('Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.')
console.log('Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.')
console.log('Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.')
console.log('Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.')
console.log('The end of the long function.')
}
```
```js {group=tab-expand name="Collapsed" .is-collapsed}
function shortFunction() {
console.log('This is a short function.')
}
```
## Code tabs inside other blocks
> [!NOTE]+
>
> ```python {group=tab-nested}
> print("Python")
> ```
>
> ```go {group=tab-nested}
> fmt.Println("Go")
> ```
{{< details open=true >}}
```python {group=tab2}
print("Python")
```
```go {group=tab2}
fmt.Println("Go")
```
{{< /details >}}
-440
View File
@@ -1,440 +0,0 @@
---
title: Code Block Test
date: 2025-11-28T15:16:35+08:00
collections:
- Tests
categories:
- Markdown
tags:
- Code Block
---
Testing code block in FixIt theme.
<!--more-->
<!-- markdownlint-disable-file blanks-around-lists ul-style ul-indent code-block-style -->
```fixit
🎉🥚 in development mode!
```
## Multiple `modes`
```js {mode="classic"}
// Classic mode
function add(a, b) {
return a + b
}
```
```js {mode="mac"}
// Mac mode
function add(a, b) {
return a + b
}
```
```js {mode="simple"}
// Simple mode
function add(a, b) {
return a + b
}
```
## Code title
```{title="Quine Clock"}
(r=()=>setInterval(t=>{for(j=o="\n",y=5;y--;document.body["inn"
+"erHTML"]="<pre>&lt"+(S="script>\n")+o+"\n\n&lt/"+S)for(x=-01;
63-!y>x++;o+=`(r=${r})()`[j++].fontcolor(c?'#FF0':"#444"))c=x/2
%4<3&&parseInt("odRFacb67o2vi5gmOZmwFNteohbOh3sw".slice(i="9"<(
D=Date()[16+(x/8|0)])?30:D*3,i+3),36)&1<<(x/2|0)%4+3*y},100))()
```
## Code File Name
```js {name="hello.js"}
function hello(x = 'world') {
console.log(`Hello, ${x}!`)
}
hello()
// Hello, world!
hello('FixIt')
// Hello, FixIt!
```
## Shadow
{{< tabs >}}
{{% tab title="Always" %}}
```js {shadow="always"}
function hello(x = 'world') {
console.log(`Hello, ${x}!`)
}
```
{{% /tab %}}
{{% tab title="Hover" %}}
```js {shadow="hover"}
function hello(x = 'world') {
console.log(`Hello, ${x}!`)
}
```
{{% /tab %}}
{{% tab title="Never" %}}
```js {shadow="never"}
function hello(x = 'world') {
console.log(`Hello, ${x}!`)
}
```
{{% /tab %}}
{{< /tabs >}}
## Collapsed/Expanded
```
eval(z = 'p="<"+"pre>"/* ,.oq#+ ,._, */;for(y in n="zw24l6k\
4e3t4jnt4qj24xh2 x/* =<,m#F^ A W###q. */42kty24wrt413n243n\
9h243pdxt41csb yz/* #K q##H######Am */43iyb6k43pk7243nm\
r24".split(4)){/* dP cpq#q##########b, */for(a in t=pars\
eInt(n[y],36)+/* p##@###YG=[#######y */(e=x=r=[]))for\
(r=!r,i=0;t[a/* d#qg `*PWo##q#######D */]>i;i+=.05)wi\
th(Math)x-= /* aem1k.com Q###KWR#### W[ */.05,0>cos(o=\
new Date/1e3/* .Q#########Md#.###OP A@ , */+x/PI)&&(e[~\
~(32*sin(o)*/* , (W#####Xx######.P^ T % */sin(.5+y/7))\
+60] =-~ r);/* #y `^TqW####P###BP */for(x=0;122>\
x;)p+=" *#"/* b. OQ####x#K */[e[x++]+e[x++\
]]||(S=("eval"/* l `X#####D , */+"(z=\'"+z.spl\
it(B = "\\\\")./* G####B" # */join(B+B).split\
(Q="\'").join(B+Q/* VQBP` */)+Q+")//m1k")[x/2\
+61*y-1]).fontcolor/* TP */(/\\w/.test(S)&&"#\
03B");document.body.innerHTML=p+=B+"\\n"}setTimeout(z)')//
```
````md
```lang {.is-collapsed}
// This code block will be collapsed by default.
```
````
````md
```lang {.is-expanded}
// This code block will be expanded regardless of its length.
```
````
## No wrapper
Set `wrapper=false` to disable code wrapper.
```js {wrapper=false}
function add(a, b) {
return a + b
}
```
```js {wrapper=false, lineNos=false}
function add(a, b) {
return a + b
}
```
## lineNos=false
```js {lineNos=false}
function add(a, b) {
return a + b
}
```
## lineNumbersInTable=false
> [!WARNING]
> Not recommended!
```js {lineNumbersInTable=false}
function add(a, b) {
return a + b
}
```
## Diff Code
```diff
- theme = "LoveIt"
+ theme = "FixIt"
! enhancements and fixes
```
## Long Code
```html
<p>Lorem ipsum dolor sit amet, graecis denique ei vel, at duo primis mandamus. Et legere ocurreret pri, animal tacimates complectitur ad cum. Cu eum inermis inimicus efficiendi. Labore officiis his ex, soluta officiis concludaturque ei qui, vide sensibus vim ad.</p>
```
<p>Lorem ipsum dolor sit amet, graecis denique ei vel, at duo primis mandamus. Et legere ocurreret pri, animal tacimates complectitur ad cum. Cu eum inermis inimicus efficiendi. Labore officiis his ex, soluta officiis concludaturque ei qui, vide sensibus vim ad.</p>
## Code Toggle
```toggle {before_tabs="hugo."}
[params]
description = ''
keywords = []
[params.codeblock]
mode = 'classic'
wrapper = true
```
## Mermaid
```mermaid
flowchart TD
A[Start] --> B{Is it?}
B -->|Yes| C[OK]
C --> D[Rethink]
D --> B
B ---->|No| E[End]
```
## ECharts
```echarts
[title]
text = "Summary Line Chart"
top = "2%"
left = "center"
[tooltip]
trigger = "axis"
[legend]
data = [
"Email Marketing",
"Affiliate Advertising",
"Video Advertising",
"Direct View",
"Search Engine"
]
top = "10%"
[grid]
left = "5%"
right = "5%"
bottom = "5%"
top = "20%"
containLabel = true
[toolbox]
left = "left"
[toolbox.feature]
[toolbox.feature.saveAsImage]
title = "Save as Image"
[xAxis]
type = "category"
boundaryGap = false
data = [
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday"
]
[yAxis]
type = "value"
[[series]]
name = "Email Marketing"
type = "line"
stack = "Total"
data = [
120.0,
132.0,
101.0,
134.0,
90.0,
230.0,
210.0
]
[[series]]
name = "Affiliate Advertising"
type = "line"
stack = "Total"
data = [
220.0,
182.0,
191.0,
234.0,
290.0,
330.0,
310.0
]
[[series]]
name = "Video Advertising"
type = "line"
stack = "Total"
data = [
150.0,
232.0,
201.0,
154.0,
190.0,
330.0,
410.0
]
[[series]]
name = "Direct View"
type = "line"
stack = "Total"
data = [
320.0,
332.0,
301.0,
334.0,
390.0,
330.0,
320.0
]
[[series]]
name = "Search Engine"
type = "line"
stack = "Total"
data = [
820.0,
932.0,
901.0,
934.0,
1290.0,
1330.0,
1320.0
]
```
## Timeline
```timeline
events:
- timestamp: 2024-07-11
content: Success
- timestamp: 2024-07-13
content: Approved
- timestamp: 2024-07-15
content: Event start
```
## JSON
```json
{
"name": "FixIt",
"version": "0.4.0",
"description": "A clean, elegant but advanced blog theme for Hugo",
"keywords": ["Hugo", "theme", "FixIt"]
}
```
## File Tree
{{< file-tree >}}
- name: src
type: dir
children:
- name: index.ts
type: file
- name: app.ts
type: file
- name: package.json
type: file
{{< /file-tree >}}
## Code block inside other blocks
> [!NOTE]+
>
> ```js {mode="classic"}
> function add(a, b) {
> return a + b
> }
> ```
{{< typeit code=java >}}
public class HelloWorld {
public static void main(String []args) {
System.out.println("Hello World");
}
}
{{< /typeit >}}
{{< details "Code Block inside Details" >}}
```js {mode="classic"}
function add(a, b) {
return a + b
}
```
{{< /details >}}
## Highlighting
Highlighting in code fences is enabled by default.
```js {linenostart=287,hl_lines=[2,"8-10"]}
/**
* check if a string is a JS object string
* @example isObjectLiteral("{a:1,b:2}") // true
* @param {string} str string to check
* @returns {boolean} whether the string is a JS object string
*/
function isObjectLiteral(str) {
if (typeof str !== 'string') {
return false
}
str = str.replace(/\s+/g, ' ').trim().replace(/;$/, '')
if (str.startsWith('{') && str.endsWith('}')) {
return true
}
return false
}
```
Highlighting in shortcode highlight.
{{< highlight javascript "hl_lines=2 8-10,linenostart=287" >}}
/**
* check if a string is a JS object string
* @example isObjectLiteral("{a:1,b:2}") // true
* @param {string} str string to check
* @returns {boolean} whether the string is a JS object string
*/
function isObjectLiteral(str) {
if (typeof str !== 'string') {
return false
}
str = str.replace(/\s+/g, ' ').trim().replace(/;$/, '')
if (str.startsWith('{') && str.endsWith('}')) {
return true
}
return false
}
{{< /highlight >}}
## Gist Embed
{{< env "production" >}}
{{< gist Lruihao fb8b2d0353465c4d40bf74818db80710 >}}
{{< /env >}}
@@ -1,60 +0,0 @@
---
title: Color Preview Test
date: 2025-08-17T17:20:00+08:00
collections:
- Tests
categories:
- Markdown
tags:
- Color Preview
---
This post is a test post to preview the color syntax in Markdown.
<!--more-->
## 📝 Syntax
| Color | Syntax | Example | Output |
| ----- | ------------------ | -------------------------- | -------------------- |
| 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%)` |
e.g. The background color is `#ffffff` for light mode and `#000000` for dark mode.
## ✅ Color Preview
Pure color values (no leading/trailing characters):
- `#0969DA`
- `#096`
- `#FF0000`
- `#00FF00`
- `rgb(255, 0, 0)`
- `rgb(0, 255, 0)`
- `hsl(240, 100%, 50%)`
- `hsl(120, 100%, 50%)`
Theme colors:
| Type | Light | Dark |
| :-------: | :-------: | :-------: |
| Primary | `#1677ff` | `#0069fc` |
| Secondary | `#8b949e` | `#7d8792` |
| Success | `#52c41a` | `#49ad17` |
| Info | `#13c2c2` | `#11abab` |
| Warning | `#faad14` | `#efa105` |
| Danger | `#ff4d4f` | `#ff3436` |
## ❌ Regular Code
With leading or trailing characters:
- `test #0969DA`
- `#0969DA test`
- `color: #0969DA`
- ` #0969DA` (leading space)
- `#0969DA ` (trailing space)
- `background-color: rgb(255, 0, 0)`
- `using hsl(240, 100%, 50%) color`
@@ -1,186 +0,0 @@
---
title: Encryption Test
date: 2022-05-21T22:31:22+08:00
description: Test for encrypting content.
password: 1212
message: Password is 1212
collections:
- Tests
categories:
- Features
tags:
- Encryption
---
<!--more-->
I was shy, so I hid.
## Ruby
[Hugo]^(An open-source static site generator)
## Math
$$ \ce{CO2 + C -> 2 CO} $$
$$ \ce{Hg^2+ ->[I-] HgI2 ->[I-] [Hg^{II}I4]^2-} $$
## JSON
```json
{
"name": "fixit",
"version": "1.0.0",
"description": "A Hugo theme for creating encrypted content.",
"author": "Lruihao"
}
```
## style
{{< style "text-align:right; strong{color:#00b1ff;}" >}}
This is a **right-aligned** paragraph.
{{< /style >}}
## Script
{{< script >}}
console.log('before decrypting');
document.addEventListener('fixit:decrypted', () => {
console.log('after decrypting')
});
{{< /script >}}
## Mermaid
```mermaid
graph LR;
A[Hard edge] -->|Link text| B(Round edge)
B --> C{Decision}
C -->|One| D[Result one]
C -->|Two| E[Result two]
```
## Echarts
```echarts
title:
text: Summary Line Chart
top: 2%
left: center
tooltip:
trigger: axis
legend:
data:
- Email Marketing
- Affiliate Advertising
- Video Advertising
- Direct View
- Search Engine
top: 10%
grid:
left: 5%
right: 5%
bottom: 5%
top: 20%
containLabel: true
toolbox:
feature:
saveAsImage:
title: Save as Image
xAxis:
type: category
boundaryGap: false
data:
- Monday
- Tuesday
- Wednesday
- Thursday
- Friday
- Saturday
- Sunday
yAxis:
type: value
series:
- name: Email Marketing
type: line
stack: Total
data:
- 120
- 132
- 101
- 134
- 90
- 230
- 210
- name: Affiliate Advertising
type: line
stack: Total
data:
- 220
- 182
- 191
- 234
- 290
- 330
- 310
- name: Video Advertising
type: line
stack: Total
data:
- 150
- 232
- 201
- 154
- 190
- 330
- 410
- name: Direct View
type: line
stack: Total
data:
- 320
- 332
- 301
- 334
- 390
- 330
- 320
- name: Search Engine
type: line
stack: Total
data:
- 820
- 932
- 901
- 934
- 1290
- 1330
- 1320
```
## Typeit
{{< typeit code=javascript >}}
console.log('before decrypting');
document.addEventListener('fixit:decrypted', () => {
console.log('after decrypting')
});
{{< /typeit >}}
## fixit-encryptor
All the following shortcodes passwords are `1212`.
{{% fixit-encryptor "1212" %}}
{{< typeit >}}如果你愿意一层一层一层地剥开我的心{{< /typeit >}}
{{% fixit-encryptor "1212" %}}
{{< typeit >}}你会发现 你会讶异{{< /typeit >}}
{{% fixit-encryptor "1212" %}}
{{< typeit >}}你是我最压抑最深处的秘密{{< /typeit >}}
{{% /fixit-encryptor %}}
{{% /fixit-encryptor %}}
{{% /fixit-encryptor %}}
@@ -1,59 +0,0 @@
[[filetree]]
name = "src-toml"
type = "dir"
[[filetree.children]]
name = "index.ts"
type = "file"
[[filetree.children]]
name = "components"
type = "dir"
[[filetree.children.children]]
name = "Header.tsx"
type = "file"
[[filetree.children.children]]
name = "Footer.tsx"
type = "file"
[[filetree.children]]
name = "utils"
type = "dir"
[[filetree.children.children]]
name = "helper.ts"
type = "file"
[[filetree.children.children]]
name = "validator.ts"
type = "file"
[[filetree]]
name = "public"
type = "dir"
[[filetree.children]]
name = "favicon.ico"
type = "file"
[[filetree.children]]
name = "images"
type = "dir"
[[filetree.children.children]]
name = "logo.png"
type = "file"
[[filetree]]
name = "package.json"
type = "file"
[[filetree]]
name = "README.md"
type = "file"
[[filetree]]
name = "tsconfig.json"
type = "file"
@@ -1,273 +0,0 @@
---
title: File Tree Test
date: 2026-01-10T03:00:48+08:00
collections:
- Tests
categories:
- Shortcodes
tags:
- file-tree
---
This article tests the **File Tree** shortcode functionality in the FixIt theme.
<!--more-->
<!-- markdownlint-disable-file MD007 MD024 MD032 -->
## Content Modes
### Shortcode body
#### JSON format
{{< file-tree >}}
[
{
"name": "src",
"type": "dir",
"children": [
{
"name": "index.ts",
"type": "file"
},
{
"name": "app.ts",
"type": "file"
}
]
},
{
"name": "README.md",
"type": "file"
},
{
"name": ".gitignore",
"type": "file"
}
]
{{< /file-tree >}}
#### YAML format
{{< file-tree folder_slash=true >}}
- name: project-root
type: dir
children:
- name: src
type: dir
children:
- name: index.ts
type: file
- name: config.ts
type: file
- name: tests
type: dir
children:
- name: unit.test.ts
type: file
- name: package.json
type: file
- name: tsconfig.json
type: file
{{< /file-tree >}}
#### TOML format
{{< file-tree >}}
[[filetree]]
name = "src"
type = "dir"
[[filetree.children]]
name = "index.ts"
type = "file"
[[filetree.children]]
name = "app.ts"
type = "file"
[[filetree]]
name = "README.md"
type = "file"
{{< /file-tree >}}
### File data
#### TOML format
{{< file-tree file="data/example.toml" />}}
TOML with folder slash and level 3:
{{< file-tree file="data/example.toml" level=3 folder_slash=true />}}
#### JSON format
{{< file-tree file="filetree/example.json" />}}
JSON with folder slash and level 2:
{{< file-tree file="filetree/example.json" level=2 folder_slash=true />}}
#### YAML format
Trying the file not found case (should fallback to next mode):
{{< file-tree file="data/nonexistent.yaml" data="example" />}}
### Hugo data
#### Basic usage
{{< file-tree data="example" />}}
#### Fully expanded
{{< file-tree data="example" level=-1 />}}
#### Limited expansion
{{< file-tree data="example" level=1 />}}
#### With folder slash
{{< file-tree data="example" folder_slash=true />}}
#### With level and folder slash
{{< file-tree data="example" level=2 folder_slash=true />}}
#### Collapsed with ignore
{{< file-tree data="example" level=0 ignore_list="README.md" />}}
## Filesystem Mode
### Basic paths
{{< file-tree />}}
{{< file-tree "." />}}
{{< file-tree "content" />}}
{{< file-tree name="{path}" />}}
{{< file-tree name="FixIt/apps/test" />}}
{{< file-tree path="posts" name="{path}" />}}
### Named parameters
{{< file-tree path="data" level=2 />}}
### Expansion levels
{{< file-tree "assets" 0 />}}
{{< file-tree path="assets" level=2 folder_slash=true />}}
{{< file-tree "assets" -1 />}}
### With ignore lists
{{< file-tree ignore_list=".hugo_build.lock, public, resources, node_modules" level=2 folder_slash=true />}}
### root not exist
path="nonexistent/path"
{{< file-tree "nonexistent/path" />}}
## Code Block Rendering
### Basic code block
YAML format:
```file-tree
- name: my-project
type: dir
children:
- name: src
type: dir
children:
- name: main.js
type: file
- name: utils.js
type: file
- name: package.json
type: file
- name: README.md
type: file
```
### TOML format
```file-tree
[[filetree]]
name = "src"
type = "dir"
[[filetree.children]]
name = "index.ts"
type = "file"
[[filetree]]
name = "README.md"
type = "file"
```
### With parameters
```file-tree {level=2 folder_slash=true ignore_list="config.local.js"}
- name: project
type: dir
children:
- name: config
type: dir
children:
- name: config.js
type: file
- name: config.local.js
type: file
- name: src
type: dir
children:
- name: index.js
type: file
- name: .gitignore
type: file
```
### Fully expanded
```file-tree {level=-1 folder_slash=true}
- name: backend
type: dir
children:
- name: api
type: dir
children:
- name: routes
type: dir
children:
- name: users.js
type: file
- name: posts.js
type: file
- name: controllers
type: dir
children:
- name: userController.js
type: file
- name: database
type: dir
children:
- name: models
type: dir
- name: migrations
type: dir
- name: app.js
type: file
```
@@ -1,82 +0,0 @@
---
title: Font Awesome Test
date: 2025-11-28T08:30:39+08:00
collections:
- Tests
categories:
- Markdown
tags:
- Font Awesome
---
Test for rendering Font Awesome icons.
<!--more-->
## Size
:(fa-solid fa-camera fa-2xs):
:(fa-solid fa-camera fa-xs):
:(fa-solid fa-camera fa-sm):
:(fa-solid fa-camera fa-lg):
:(fa-solid fa-camera fa-xl):
:(fa-solid fa-camera fa-2xl):
:(fa-solid fa-camera fa-1x):
:(fa-solid fa-camera fa-2x):
:(fa-solid fa-camera fa-3x):
:(fa-solid fa-camera fa-5x):
:(fa-solid fa-camera fa-7x):
:(fa-solid fa-camera fa-10x):
## Fixed width
:(fa-solid fa-skating fa-2x): Skating\
:(fa-solid fa-skiing fa-2x): Skiing\
:(fa-solid fa-skiing-nordic fa-2x): Nordic Skiing
## List icon
:(fa-regular fa-check-square): Eat a hamburger\
:(fa-regular fa-square): Get a girlfriend
:(fa-regular fa-check-circle): Go to beach\
:(fa-regular fa-circle): Go to Tibet
## Rotate
:(fa-solid fa-snowboarding):
:(fa-solid fa-snowboarding fa-rotate-90):
:(fa-solid fa-snowboarding fa-rotate-180):
:(fa-solid fa-snowboarding fa-rotate-270):
## Flip
:(fa-solid fa-snowboarding):
:(fa-solid fa-snowboarding fa-flip-horizontal):
:(fa-solid fa-snowboarding fa-flip-vertical):
:(fa-solid fa-snowboarding fa-flip-both):
## Animation
:(fa-solid fa-spinner):
:(fa-solid fa-spinner fa-spin):
:(fa-solid fa-spinner fa-pulse):
:(fa-solid fa-circle-notch fa-spin):
:(fa-solid fa-circle-notch fa-pulse):
:(fa-solid fa-sync fa-spin):
:(fa-solid fa-sync fa-pulse):
:(fa-solid fa-cog fa-spin):
:(fa-solid fa-cog fa-pulse):
## Float
:(fa-solid fa-quote-left fa-pull-left):
hey guys!
{.text-center}
:(fa-solid fa-quote-right fa-pull-right):
## Border
:(fa-brands fa-apple fa-border fa-10x):
@@ -1,84 +0,0 @@
---
title: JSON Viewer Test
date: 2025-10-14T12:29:06+08:00
collections:
- Tests
categories:
- Markdown
tags:
- json
---
Testing JSON viewer in FixIt theme.
```json {boxed=false}
{
"foo": "bar"
}
```
<!--more-->
## JSON Viewer
```json
{
"name": "John Doe",
"age": 30,
"isEmployed": true,
"address": {
"street": "123 Main St",
"city": "Anytown",
"state": "CA",
"postalCode": "12345"
},
"phoneNumbers": [
{
"type": "home",
"number": "555-1234"
},
{
"type": "work",
"number": "555-5678"
}
],
"children": [],
"spouse": null
}
```
disabled copy:
```json {copyable=false}
{
"foo": "bar"
}
```
## JSON Code
```json {enable=false}
{
"name": "John Doe",
"age": 30,
"isEmployed": true,
"address": {
"street": "123 Main St",
"city": "Anytown",
"state": "CA",
"postalCode": "12345"
},
"phoneNumbers": [
{
"type": "home",
"number": "555-1234"
},
{
"type": "work",
"number": "555-5678"
}
],
"children": [],
"spouse": null
}
```
-81
View File
@@ -1,81 +0,0 @@
---
title: KaTeX Test
date: 2025-09-15T21:05:17+08:00
collections:
- Tests
categories:
- Markdown
tags:
- Math
---
Testing $\KaTeX$ rendering in FixIt theme.
<!--more-->
## Inline Formulas
$c = \pm\sqrt{a^2 + b^2}$ and \(f(x)=\int_{-\infty}^{\infty} \hat{f}(\xi) e^{2 \pi i \xi x} d \xi\)
## Formula Blocks
$$ c = \pm\sqrt{a^2 + b^2} $$
\[f(x)=\int_{-\infty}^{\infty} \hat{f}(\xi) e^{2 \pi i \xi x} d \xi\]
$$
\begin{equation*}
\rho \frac{\mathrm{D} \mathbf{v}}{\mathrm{D} t}=\nabla \cdot \mathbb{P}+\rho \mathbf{f}
\end{equation*}
$$
$$
\begin{equation}
\mathbf{E}=\sum_{i} \mathbf{E}\_{i}=\mathbf{E}\_{1}+\mathbf{E}\_{2}+\mathbf{E}_{3}+\cdots
\end{equation}
$$
$$
\begin{align}
a&=b+c \\
d+e&=f
\end{align}
$$
$$
\begin{alignat}{2}
10&x+&3&y = 2 \\
3&x+&13&y = 4
\end{alignat}
$$
$$
\begin{gather}
a=b \\
e=b+c
\end{gather}
$$
$$
\begin{CD}
A @>a>> B \\
@VbVV @AAcA \\
C @= D
\end{CD}
$$
## Chemical Equations
$$ \ce{CO2 + C -> 2 CO} $$
$$ \ce{Hg^2+ ->[I-] HgI2 ->[I-] [Hg^{II}I4]^2-} $$
$$C_p[\ce{H2O(l)}] = \pu{75.3 J // mol K}$$
## $\KaTeX$ in headings
This is a bug:
```latex
## $\KaTeX$ in headings
```
-93
View File
@@ -1,93 +0,0 @@
---
title: Link Rendering Test
date: 2026-04-10T11:40:06+08:00
collections:
- Tests
categories:
- Markdown
tags:
- Link
link:
guard:
enable: true
# mode: redirect
allow_domains:
- demo.fixit.lruihao.cn
---
This post validates link rendering paths in FixIt, including Markdown render hook and link shortcode modes.
<!--more-->
## Markdown Render Hook (Regular Link)
These links are rendered by `layouts/_markup/render-link.html` and should always produce regular links.
- Internal relative link: [Task list test](/test/units/task-list-test/)
- Internal anchor link: [Jump to Card Link section](#card-link-shortcode)
- Absolute same-site link: [Test site home](http://demo.fixit.lruihao.cn/test/)
- External HTTP link: [FixIt Repository](https://github.com/hugo-fixit/FixIt)
- Mail link: [Email test](mailto:test@gmail.com)
- JavaScript link: [JavaScript test](javascript:void(0))
- Tel link: [Phone test](tel:+1234567890)
- File link: [File test](file:///path/to/file.txt)
- Data link: [Data URI test](data:text/plain;base64,SGVsbG8sIFdvcmxkIQ==)
### Title Attribute (Markdown)
[External link with title](https://google.com "Example Title")
## Link Shortcode (Regular)
### Named parameters
{{< link href="https://github.com/hugo-fixit/FixIt" content="GitHub via shortcode" title="GitHub title" >}}
{{< link href="/test/units/codeblock-test/" content="Internal shortcode link" class="shortcode-link-test" >}}
{{< link href="https://google.com" content="Custom rel + no noreferrer" rel="ugc" noreferrer=false >}}
{{< link href="/images/fixit.svg" content="Download local file" download="fixit.svg" >}}
### Positional parameters
{{< link "https://mozilla.org" "Positional regular link" "Positional title" >}}
## Card Link Shortcode
### Basic card
{{< link href="https://fixit.lruihao.cn" content="FixIt Documentation" card=true >}}
### Card with custom icon class
{{< link href="https://github.com/hugo-fixit/FixIt" content="FixIt on GitHub" card=true card-icon="fa-brands fa-github" >}}
### Card with custom image icon
{{< link href="https://gohugo.io" content="Hugo Official Site" card=true card-icon="/images/hugo.svg" >}}
### Card with download state
{{< link href="/images/fixit.svg" content="Download as card" card=true download="fixit.svg" >}}
### Positional card parameters
{{< link "https://google.com" "Positional card link" "" true "fa-solid fa-link" >}}
## Edge Cases
- URL with query string:
[Search query test](https://google.com/search?q=fixit&lang=en)
- URL with fragment:
[Fragment test](https://google.com/docs#installation)
- Long URL display (card meta should trim protocol automatically):
{{< link href="https://google.com/a/very/long/path/for/testing/card/url/display?foo=bar&baz=qux" content="Long URL card" card=true >}}
## Manual Verification Checklist
- Regular Markdown external links include external behavior and icon policy.
- Internal links are not treated as external.
- Shortcode card links render `.card-link` structure and card meta URL.
- `download` shows download icon/state in both regular and card modes.
- `noreferrer=false` removes `noopener noreferrer` from generated rel values.
-150
View File
@@ -1,150 +0,0 @@
---
title: MathJax Test
date: 2025-09-15T21:05:17+08:00
collections:
- Tests
categories:
- Markdown
tags:
- Math
math:
type: mathjax
mathjax:
macros:
bold: ["{\\bf #1}", 1] # usage: $\bold{math}$
loader:
load: ["ui/safe", "[tex]/physics", "[custom]/xypic.js"]
paths:
custom: "https://cdn.jsdelivr.net/gh/sonoisa/XyJax-v3@3.0.1/build/"
packages:
"[+]": ["physics", "xypic"]
tex:
physics:
italicdiff: false
arrowdel: false
---
Testing $\text{MathJax}$ rendering in FixIt theme.
<!--more-->
## Inline Formulas
$c = \pm\sqrt{a^2 + b^2}$ and \(f(x)=\int_{-\infty}^{\infty} \hat{f}(\xi) e^{2 \pi i \xi x} d \xi\)
## Formula Blocks
$$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$
\[ f(a) = \frac{1}{2\pi i} \oint\frac{f(z)}{z-a}dz \]
$$
\cos(\theta+\phi)=\cos(\theta)\cos(\phi)\sin(\theta)\sin(\phi)
$$
\[
\int_D ({\nabla\cdot} F)dV=\int_{\partial D} F\cdot ndS
\]
$$
\vec{\nabla} \times \vec{F} =
\left( \frac{\partial F_z}{\partial y} - \frac{\partial F_y}{\partial z} \right) \mathbf{i}
+ \left( \frac{\partial F_x}{\partial z} - \frac{\partial F_z}{\partial x} \right) \mathbf{j}
+ \left( \frac{\partial F_y}{\partial x} - \frac{\partial F_x}{\partial y} \right) \mathbf{k}
$$
$$
\sigma = \sqrt{ \frac{1}{N} \sum_{i=1}^N (x_i -\mu)^2}
$$
$$
(\nabla_X Y)^k = X^i (\nabla_i Y)^k =
X^i \left( \frac{\partial Y^k}{\partial x^i} + \Gamma_{im}^k Y^m \right)
$$
## Chemical Equations
$$C_p[\ce{H2O(l)}] = \pu{75.3 J // mol K}$$
$$ \ce{Hg^2+ ->[I-] HgI2 ->[I-] [Hg^{II}I4]^2-} $$
$$C_p[\ce{H2O(l)}] = \pu{75.3 J // mol K}$$
## Custom Macros
$\bold{Custom}$ macro $\KaTeX$ in $\text{MathJax}$
$$
\def\RR{{\bf R}}
\def\bolda#1{{\bf #1}}
\RR = \bolda{R}
$$
$$
\newcommand{\water}{{\rm H_{2}O}}
\water = \text{H}_2\text{O}
$$
$$
\newcommand{\hello}[1][World]{Hello, #1!}
\hello \quad \hello[FixIt]
$$
$$
\let\oldphi=\phi
\let\oldtheta=\theta
\renewcommand{\phi}{\varphi}
\renewcommand{\theta}{\vartheta}
\phi, \oldphi, \theta, \oldtheta
$$
## Custom Extensions
A `physics` package example:
$$
\mqty(a & b \\ c & d) = \begin{pmatrix} a & b \\ c & d \end{pmatrix}
$$
An `xypic` package example:
$$
\begin{xy}
\xymatrix {
U \ar@/_/[ddr]_y \ar@{.>}[dr]|{\langle x,y \rangle} \ar@/^/[drr]^x \\
& X \times_Z Y \ar[d]^q \ar[r]_p & X \ar[d]_f \\
& Y \ar[r]^g & Z
}
\end{xy}
$$
## \$\\text{MathJax}\$ in headings
```latex
## \$\\text{MathJax}\$ in headings
```
## More
### Dark Mode Adaptation
Use `.auto-dark-mode` class or `auto-dark` shortcode to automatically adapt to dark mode by inverting the color and hue:
For inline formula:
$\bbox[border: solid .4pt magenta, pink]{x^2=4}$
{.auto-dark-mode}
For formula blocks:
{{< auto-dark >}}
$$
\bbox[border: solid .4pt magenta, pink]{x^2=4}
$$
{{< /auto-dark >}}
### In Encrypted Content
{{% fixit-encryptor "1212" %}}
$c = \pm\sqrt{a^2 + b^2}$ and \(f(x)=\int_{-\infty}^{\infty} \hat{f}(\xi) e^{2 \pi i \xi x} d \xi\)
{{% /fixit-encryptor %}}
@@ -1,561 +0,0 @@
---
title: Mermaid Diagrams Test
date: 2025-08-20T10:00:00+08:00
collections:
- Tests
categories:
- Markdown
- Shortcodes
tags:
- Mermaid
- Diagrams
mermaid:
zenuml: https://cdn.jsdelivr.net/npm/@mermaid-js/mermaid-zenuml/dist/mermaid-zenuml.esm.min.mjs
---
The FixIt theme supports two ways to use Mermaid: code block syntax and shortcode syntax.
```mermaid {wrapper=false}
---
config:
theme: 'forest'
---
graph TD
a --> b
```
<!--more-->
## Flowchart
```mermaid
flowchart TD
A[Start] --> B{Is it?}
B -->|Yes| C[OK]
C --> D[Rethink]
D --> B
B ---->|No| E[End]
```
## Sequence Diagram
```mermaid
sequenceDiagram
participant Alice
participant Bob
Alice->>John: Hello John, how are you?
loop Healthcheck
John->>John: Fight against hypochondria
end
Note right of John: Rational thoughts <br/>prevail!
John-->>Alice: Great!
John->>Bob: How about you?
Bob-->>John: Jolly good!
```
## Gantt Chart
{{< mermaid >}}
gantt
title A Gantt Diagram
dateFormat YYYY-MM-DD
section Section
A task :a1, 2014-01-01, 30d
Another task :after a1 , 20d
section Another
Task in sec :2014-01-12 , 12d
another task : 24d
{{< /mermaid >}}
## Class Diagram
```mermaid
classDiagram
Animal <|-- Duck
Animal <|-- Fish
Animal <|-- Zebra
Animal : +int age
Animal : +String gender
Animal: +isMammal()
Animal: +mate()
class Duck{
+String beakColor
+swim()
+quack()
}
class Fish{
-int sizeInFeet
-canEat()
}
class Zebra{
+bool is_wild
+run()
}
```
## State Diagram
```mermaid
stateDiagram-v2
[_] --> Still
Still --> [_]
Still --> Moving
Moving --> Still
Moving --> Crash
Crash --> [*]
```
## Entity Relationship Diagram
```mermaid
erDiagram
CUSTOMER ||--o{ ORDER : places
ORDER ||--|{ LINE-ITEM : contains
CUSTOMER }|..|{ DELIVERY-ADDRESS : uses
CUSTOMER {
string name
string custNumber
string sector
}
ORDER {
int orderNumber
string deliveryAddress
}
LINE-ITEM {
string productCode
int quantity
float pricePerUnit
}
```
## User Journey
{{< mermaid >}}
journey
title My working day
section Go to work
Make tea: 5: Me
Go upstairs: 3: Me
Do work: 1: Me, Cat
section Go home
Go downstairs: 5: Me
Sit down: 5: Me
{{< /mermaid >}}
## Git Graph
```mermaid
gitGraph
commit
branch hotfix
checkout hotfix
commit
branch develop
checkout develop
commit id:"ash" tag:"abc"
branch featureB
checkout featureB
commit type:HIGHLIGHT
checkout main
checkout hotfix
commit type:NORMAL
checkout develop
commit type:REVERSE
checkout featureB
commit
checkout main
merge hotfix
checkout featureB
commit
checkout develop
branch featureA
commit
checkout develop
merge hotfix
checkout featureA
commit
checkout featureB
commit
checkout develop
merge featureA
branch release
checkout release
commit
checkout main
commit
checkout release
merge main
checkout develop
merge release
```
## Pie Chart
{{< mermaid >}}
pie title What Voldemort doesn't have?
"FRIENDS" : 2
"FAMILY" : 3
"NOSE" : 45
{{< /mermaid >}}
## Quadrant Chart
```mermaid
quadrantChart
title Reach and influence
x-axis Low Reach --> High Reach
y-axis Low Influence --> High Influence
quadrant-1 We should expand
quadrant-2 Need to promote
quadrant-3 Re-evaluate
quadrant-4 May be improved
Campaign A: [0.3, 0.6]
Campaign B: [0.45, 0.23]
Campaign C: [0.57, 0.69]
Campaign D: [0.78, 0.34]
Campaign E: [0.40, 0.34]
```
## Timeline
```mermaid
timeline
title History of Social Media Platform
2002 : LinkedIn
2003 : MySpace
: Skype
2004 : Facebook
: Gmail
2005 : Youtube
2006 : Twitter
2007 : FourSquare
2008 : Github
2010 : Instagram
2011 : Snapchat
2012 : Discord
```
## Mindmap
```mermaid
mindmap
root((mindmap))
Origins
Long history
::icon(fa fa-book)
Popularisation
British popular psychology author Tony Buzan
Research
On effectiveness<br/>and features
On Automatic creation
Uses
Creative techniques
Strategic planning
Argument mapping
Tools
Pen and paper
Mermaid
```
## XY Chart
{{< mermaid >}}
xychart-beta
title "Sales Revenue"
x-axis [jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec]
y-axis "Revenue (in $)" 4000 --> 11000
bar [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000]
line [5000, 6000, 7500, 8200, 9500, 10500, 11000, 10200, 9200, 8500, 7000, 6000]
{{< /mermaid >}}
## Requirement Diagram
```mermaid
requirementDiagram
requirement test_req {
id: 1
text: the test text.
risk: high
verifymethod: test
}
element test_entity {
type: simulation
}
test_entity - satisfies -> test_req
```
## C4 Architecture
```mermaid
C4Context
title System Context diagram for Internet Banking System
Enterprise_Boundary(b0, "BankBoundary0") {
Person(customerA, "Banking Customer A", "A customer of the bank, with personal bank accounts.")
Person(customerB, "Banking Customer B")
Person_Ext(customerC, "Banking Customer C", "desc")
Person(customerD, "Banking Customer D", "A customer of the bank, <br/> with personal bank accounts.")
System(SystemAA, "Internet Banking System", "Allows customers to view information about their bank accounts, and make payments.")
Enterprise_Boundary(b1, "BankBoundary") {
SystemDb_Ext(SystemE, "Mainframe Banking System", "Stores all of the core banking information about customers, accounts, transactions, etc.")
System_Boundary(b2, "BankBoundary2") {
System(SystemA, "Banking System A")
System(SystemB, "Banking System B", "A system of the bank, with personal bank accounts. next line.")
}
System_Ext(SystemC, "E-mail system", "The internal Microsoft Exchange e-mail system.")
SystemDb(SystemD, "Banking System D Database", "A system of the bank, with personal bank accounts.")
Boundary(b3, "BankBoundary3", "boundary") {
SystemQueue(SystemF, "Banking System F Queue", "A system of the bank.")
SystemQueue_Ext(SystemG, "Banking System G Queue", "A system of the bank, with personal bank accounts.")
}
}
}
BiRel(customerA, SystemAA, "Uses")
BiRel(SystemAA, SystemE, "Uses")
Rel(SystemAA, SystemC, "Sends e-mails", "SMTP")
Rel(SystemC, customerA, "Sends e-mails to")
UpdateElementStyle(customerA, $fontColor="red", $bgColor="grey", $borderColor="red")
UpdateRelStyle(customerA, SystemAA, $textColor="blue", $lineColor="blue", $offsetX="5")
UpdateRelStyle(SystemAA, SystemE, $textColor="blue", $lineColor="blue", $offsetY="-10")
UpdateRelStyle(SystemAA, SystemC, $textColor="blue", $lineColor="blue", $offsetY="-40", $offsetX="-50")
UpdateRelStyle(SystemC, customerA, $textColor="red", $lineColor="red", $offsetX="-50", $offsetY="20")
UpdateLayoutConfig($c4ShapeInRow="3", $c4BoundaryInRow="1")
```
## ZenUML
{{< mermaid >}}
zenuml
title Demo
Alice->John: Hello John, how are you?
John->Alice: Great!
Alice->John: See you later!
{{< /mermaid >}}
## Sankey Diagram
```mermaid
---
config:
sankey:
showValues: false
---
sankey-beta
Agricultural 'waste',Bio-conversion,124.729
Bio-conversion,Liquid,0.597
Bio-conversion,Losses,26.862
Bio-conversion,Solid,280.322
Bio-conversion,Gas,81.144
Biofuel imports,Liquid,35
Biomass imports,Solid,35
Coal imports,Coal,11.606
Coal reserves,Coal,63.965
Coal,Solid,75.571
District heating,Industry,10.639
District heating,Heating and cooling - commercial,22.505
District heating,Heating and cooling - homes,46.184
Electricity grid,Over generation / exports,104.453
Electricity grid,Heating and cooling - homes,113.726
Electricity grid,H2 conversion,27.14
Electricity grid,Industry,342.165
Electricity grid,Road transport,37.797
Electricity grid,Agriculture,4.412
Electricity grid,Heating and cooling - commercial,40.858
Electricity grid,Losses,56.691
Electricity grid,Rail transport,7.863
Electricity grid,Lighting & appliances - commercial,90.008
Electricity grid,Lighting & appliances - homes,93.494
Gas imports,Ngas,40.719
Gas reserves,Ngas,82.233
Gas,Heating and cooling - commercial,0.129
Gas,Losses,1.401
Gas,Thermal generation,151.891
Gas,Agriculture,2.096
Gas,Industry,48.58
Geothermal,Electricity grid,7.013
H2 conversion,H2,20.897
H2 conversion,Losses,6.242
H2,Road transport,20.897
Hydro,Electricity grid,6.995
Liquid,Industry,121.066
Liquid,International shipping,128.69
Liquid,Road transport,135.835
Liquid,Domestic aviation,14.458
Liquid,International aviation,206.267
Liquid,Agriculture,3.64
Liquid,National navigation,33.218
Liquid,Rail transport,4.413
Marine algae,Bio-conversion,4.375
Ngas,Gas,122.952
Nuclear,Thermal generation,839.978
Oil imports,Oil,504.287
Oil reserves,Oil,107.703
Oil,Liquid,611.99
Other waste,Solid,56.587
Other waste,Bio-conversion,77.81
Pumped heat,Heating and cooling - homes,193.026
Pumped heat,Heating and cooling - commercial,70.672
Solar PV,Electricity grid,59.901
Solar Thermal,Heating and cooling - homes,19.263
Solar,Solar Thermal,19.263
Solar,Solar PV,59.901
Solid,Agriculture,0.882
Solid,Thermal generation,400.12
Solid,Industry,46.477
Thermal generation,Electricity grid,525.531
Thermal generation,Losses,787.129
Thermal generation,District heating,79.329
Tidal,Electricity grid,9.452
UK land based bioenergy,Bio-conversion,182.01
Wave,Electricity grid,19.013
Wind,Electricity grid,289.366
```
## Block Diagram
{{< mermaid >}}
block-beta
columns 1
db(("DB"))
blockArrowId6<["&nbsp;&nbsp;&nbsp;"]>(down)
block:ID
A
B["A wide one in the middle"]
C
end
space
D
ID --> D
C --> D
style B fill:#969,stroke:#333,stroke-width:4px
{{< /mermaid >}}
## Packet Diagram
```mermaid
packet-beta
title Sample packet
0-15: "Source Port"
16-31: "Destination Port"
32-63: "Sequence Number"
64-95: "Acknowledgment Number"
96-99: "Data Offset"
100-105: "Reserved"
106: "URG"
107: "ACK"
108: "PSH"
109: "RST"
110: "SYN"
111: "FIN"
112-127: "Window"
128-143: "Checksum"
144-159: "Urgent Pointer"
160-191: "Options and Padding"
192-223: "Data (variable length)"
```
## Kanban
```mermaid
kanban
Todo
[Create a git repository]
[Write some code]
[Commit the code]
In Progress
[Push to main]
Done
[Merge PR]
```
## Architecture Diagram
```mermaid
architecture-beta
group api(cloud)[API]
service db(database)[Database] in api
service disk1(disk)[Storage] in api
service disk2(disk)[Storage] in api
service server(server)[Server] in api
db:L -- R:server
disk1:T -- B:server
disk2:T -- B:db
```
## Radar Chart
```mermaid
---
title: "Grades"
---
radar-beta
axis m["Math"], s["Science"], e["English"]
axis h["History"], g["Geography"], a["Art"]
curve a["Alice"]{85, 90, 80, 70, 75, 90}
curve b["Bob"]{70, 75, 85, 80, 90, 85}
max 100
min 0
```
## Treemap
```mermaid
---
config:
treemap:
valueFormat: '$0,0'
---
treemap-beta
"Budget"
"Operations"
"Salaries": 700000
"Equipment": 200000
"Supplies": 100000
"Marketing"
"Advertising": 400000
"Events": 100000
```
---
The above test cases cover the main Mermaid diagram types, including:
**Core Diagrams:**
- Flowcharts, Sequence Diagrams, Gantt Charts
- Class Diagrams, State Diagrams, Entity Relationship Diagrams
- User Journey, Git Graph, Pie Charts
**Advanced Diagrams:**
- Quadrant Charts, Timeline, Mindmaps
- XY Charts, Requirement Diagrams, C4 Architecture
- ZenUML, Sankey, Block Diagrams
**Experimental Diagrams (🔥):**
- Packet, Kanban, Architecture
- Radar Charts, Treemap
Each diagram type provides examples using both code block and shortcode syntax.
@@ -1,189 +0,0 @@
---
title: اختبار دعم اللغة العربية والكتابة من اليمين إلى اليسار
date: 2026-08-23T10:00:00+08:00
collections:
- اختبارات
categories:
- ميزات
tags:
- RTL
- عربي
- اختبار
---
هذا مقال اختباري شامل لدعم اللغة العربية والكتابة من اليمين إلى اليسار في سمة [FixIt](https://github.com/hugo-fixit/FixIt/). يهدف هذا المقال إلى اختبار جميع عناصر الويب المختلفة مع المحتوى العربي.
<!--more-->
## المقدمة
مرحباً بكم في هذا المقال الاختباري الشامل. اللغة العربية هي واحدة من أكثر اللغات انتشاراً في العالم، وتتميز بكتابتها من اليمين إلى اليسار. يتطلب دعم هذه اللغة في تصميمات الويب اهتماماً خاصاً بالعديد من الجوانب التقنية.
### لماذا RTL مهم؟
عندما نصمم مواقع ويب تدعم اللغات التي تُكتب من اليمين إلى اليسار، يجب علينا مراعاة عدة عوامل:
- **اتجاه النص**: يجب أن يتدفق النص بشكل طبيعي من اليمين إلى اليسار
- **تخطيط الصفحة**: يجب أن تكون العناصر مرتبة بشكل منطقي
- **الرموز والأيقونات**: قد تحتاج بعضها إلى انعكاس
- **التباعد بين الأسطر**: يحتاج النص العربي إلى مساحة أكبر للتشكيل
## النص المختلط
هذا نص يحتوي على كلمات إنجليزية مثل JavaScript و HTML و CSS مع نص عربي. يجب أن يظهر كل شيء بشكل صحيح.
## الروابط
- [موقع Hugo](https://gohugo.io)
- [سمة FixIt](https://fixit.lruihao.cn)
- [وثائق RTL](https://rtlstyling.com)
## القوائم
القوائم غير المرتبة:
- عنصر القائمة الأول
- عنصر القائمة الثاني
- عنصر القائمة الثالث
- عنصر فرعي
- عنصر فرعي آخر
القوائم المرتبة:
1. الخطوة الأولى في العملية
2. الخطوة الثانية
3. الخطوة الثالثة والأخيرة
قوائم المهام:
- [x] إعداد بيئة التطوير
- [x] كتابة المحتوى الأساسي
- [ ] اختبار التوافق مع المتصفحات
- [ ] مراجعة التصميم النهائي
- [ ] نشر الموقع
## الجداول
| اللغة | الاتجاه | الحروف المتصلة |
| ---------: | ------: | -------------: |
| العربية | RTL | نعم |
| الفارسية | RTL | نعم |
| العبرية | RTL | لا |
| الإنجليزية | LTR | لا |
## الاقتباسات
> العلم نور والجهل ظلام
> — مثل عربي
اقتباس طويل:
> إن الله لا يغير ما بقوم حتى يغيروا ما بأنفسهم وإذا أراد الله بقوم سوءاً فلا مرد له وما لهم من دونه من وال
## الأيقونات
أيقونات يتم قلبها في RTL:
- :(fa-solid fa-tag): وسم
- :(fa-solid fa-tags): وسوم
- :(fa-solid fa-folder): مجلد
- :(fa-solid fa-folder-open): مجلد مفتوح
- :(fa-solid fa-pen-to-square): قلم تعديل
أيقونات لا يتم قلبها في RTL:
- :(fa-solid fa-share): مشاركة
- :(fa-solid fa-search): بحث
## التبويبات
{{< tabs >}}
{{% tab title="العلامة الأولى" %}}
محتوى التبويب الأول.
{{% /tab %}}
{{% tab title="العلامة الثانية" %}}
محتوى التبويب الثاني.
{{% /tab %}}
{{< /tabs >}}
## التفاصيل القابلة للطي
<details>
<summary>انقر لعرض التفاصيل</summary>
هذا محتوى مخفي يمكنBOOLE توسيعه بالنقر.
المحتوى يمكن أن يكون نصاً أو كوداً أو أي عنصر آخر.
</details>
## التنبيهات
{{< admonition >}}
هذا تنبيه عادي يحتوي على معلومات مفيدة للمستخدم.
{{< /admonition >}}
> [!IMPORTANT]
> تأكد من اختبار جميع التغييرات قبل النشر.
## المحتوى المشفر
{{< fixit-encryptor password="1212" message="أدخل كلمة المرور (1212) لعرض المحتوى" >}}
هذا محتوى مشفر. يجب إدخال كلمة المرور لعرضه.
{{< /fixit-encryptor >}}
## أمثلة على المحتوى LTR
في صفحة RTL، بعض العناصر تبقى باتجاه LTR لأن محتاها لغوي بحت أو برمجي. فيما يلي أمثلة:
### كتلة الكود
```c
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}
```
### عارض JSON
```json
{
"name": "FixIt",
"version": "1.0.0",
"features": ["RTL", "i18n", "shortcodes"]
}
```
### تبويبات الكود
```python {group=tab1}
print("Python")
```
```go {group=tab1}
fmt.Println("Go")
```
### الصيغ الرياضية
معادلة بسيطة: $E = mc^2$
معادلة معقدة:
$$\sum_{i=1}^{n} i = \frac{n(n+1)}{2}$$
### مخططات Mermaid
```mermaid
graph LR
A[بداية] --> B[عملية]
B --> C[نهاية]
```
---
{.awesome-hr}
_تم إنشاء هذا المقال لاختبار دعم اللغة العربية في سمة FixIt._
@@ -1,187 +0,0 @@
---
title: Arabic RTL Test
date: 2026-08-23T10:00:00+08:00
collections:
- Tests
categories:
- Features
tags:
- RTL
- Arabic
---
A comprehensive test article for Arabic language and Right-to-Left layout support in the [FixIt](https://github.com/hugo-fixit/FixIt/) theme. This article tests various web elements with Arabic content.
<!--more-->
## Introduction
Welcome to this comprehensive test article. Arabic is one of the most widely spoken languages in the world, characterized by its Right-to-Left writing direction. Supporting this language in web designs requires special attention to many technical aspects.
### Why RTL Matters
When designing websites that support Right-to-Left languages, we need to consider several factors:
- **Text direction**: Text should flow naturally from right to left
- **Page layout**: Elements should be arranged in a logical order
- **Symbols and icons**: Some may need to be mirrored
- **Line spacing**: Arabic text needs more space for diacritics
## Mixed Text
This text contains English words like JavaScript, HTML, and CSS alongside Arabic text. Everything should display correctly.
## Links
- [Hugo Website](https://gohugo.io)
- [FixIt Theme](https://fixit.lruihao.cn)
- [RTL Styling](https://rtlstyling.com)
## Lists
Unordered lists:
- First list item
- Second list item
- Third list item
- Sub item
- Another sub item
Ordered lists:
1. First step in the process
2. Second step
3. Third and final step
Task lists:
- [x] Set up development environment
- [x] Write basic content
- [ ] Test browser compatibility
- [ ] Review final design
- [ ] Deploy website
## Tables
| Language | Direction | Connected Letters |
| ---------- | --------- | ----------------- |
| Arabic | RTL | Yes |
| Persian | RTL | Yes |
| Hebrew | RTL | No |
| English | LTR | No |
## Blockquotes
> Knowledge is light and ignorance is darkness
> — Arabic proverb
Long quote:
> Indeed, Allah does not change the condition of a people until they change what is in themselves
## Icons
Icons that are flipped in RTL:
- :(fa-solid fa-tag): Tag
- :(fa-solid fa-tags): Tags
- :(fa-solid fa-folder): Folder
- :(fa-solid fa-folder-open): Folder Open
- :(fa-solid fa-pen-to-square): Edit
Icons that are NOT flipped in RTL:
- :(fa-solid fa-share): Share
- :(fa-solid fa-search): Search
## Tabs
{{< tabs >}}
{{% tab title="First Tab" %}}
Content of the first tab.
{{% /tab %}}
{{% tab title="Second Tab" %}}
Content of the second tab.
{{% /tab %}}
{{< /tabs >}}
## Collapsible Details
<details>
<summary>Click to show details</summary>
This is hidden content that can be expanded by clicking.
Content can be text, code, or any other element.
</details>
## Alerts
{{< admonition >}}
This is a regular admonition with useful information for the user.
{{< /admonition >}}
> [!IMPORTANT]
> Make sure to test all changes before deploying.
## Encrypted Content
{{< fixit-encryptor password="1212" message="Enter password (1212) to view content" >}}
This is encrypted content. You must enter the password to view it.
{{< /fixit-encryptor >}}
## LTR Content Examples
In an RTL page, some elements remain in LTR direction because their content is purely linguistic or programmatic. Here are examples:
### Code Block
```c
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}
```
### JSON Viewer
```json
{
"name": "FixIt",
"version": "1.0.0",
"features": ["RTL", "i18n", "shortcodes"]
}
```
### Code Tabs
```python {group=tab1}
print("Python")
```
```go {group=tab1}
fmt.Println("Go")
```
### Math
Simple equation: $E = mc^2$
Complex equation:
$$\sum_{i=1}^{n} i = \frac{n(n+1)}{2}$$
### Mermaid Diagram
```mermaid
graph LR
A[Start] --> B[Process]
B --> C[End]
```
---
_Created to test Arabic language support in the FixIt theme._
@@ -1,29 +0,0 @@
---
title: Custom Script & Style Test
date: 2025-09-16T09:57:28+08:00
collections:
- Tests
categories:
- Shortcodes
tags:
- Script
- Style
---
Testing custom script and style by shortcode in FixIt theme.
<!--more-->
## Script
{{< script >}}
console.log('Hello FixIt!');
{{< /script >}}
See the output in the console of the developer tool.
## Style
{{< style "text-align:right; strong{color:#00b1ff;}" >}}
This is a **right-aligned** paragraph.
{{< /style >}}
@@ -1,242 +0,0 @@
---
title: Tabs Comprehensive Test Cases
date: 2025-09-09T10:00:00+08:00
collections:
- Tests
categories:
- Shortcodes
tags:
- Tabs
- UI Components
---
Testing various configurations and nested scenarios for the Tabs shortcode.
{{< tabs >}}
{{% tab title="Test Cases" %}}
See Types section for various test cases.
```go-template {name="Shortcode"}
{{</* tabs */>}}
{{%/* tab title="Test Cases" */%}}
{{%/* tab title="Test Cases" */%}}See Types section for various test cases.{{%/* /tab */%}}
{{%/* tab title="Nested Tabs" */%}}See Nested Tabs section for examples.{{%/* /tab */%}}
{{</* /tabs */>}}
```
{{% /tab %}}
{{% tab title="Nested Tabs" %}}See Nested Tabs section for examples.{{% /tab %}}
{{< /tabs >}}
<!--more-->
## Types
### Underline (Default)
<!-- placement: top, bottom, start, end -->
{{< tabs placement="top" >}}
{{% tab title="Tab 1" %}}Content for underline style tab 1{{% /tab %}}
{{% tab title="Tab 2" %}}Content for underline style tab 2{{% /tab %}}
{{% tab title="Tab 3" %}}Content for underline style tab 3{{% /tab %}}
{{< /tabs >}}
### Pill
<!-- placement: top, bottom, start, end -->
{{< tabs type="pill" placement="top" >}}
{{% tab title="Tab 1" %}}Content for pill style tab 1{{% /tab %}}
{{% tab title="Tab 2" %}}Content for pill style tab 2{{% /tab %}}
{{% tab title="Tab 3" %}}Content for pill style tab 3{{% /tab %}}
{{< /tabs >}}
### Card
<!-- placement: top, bottom, start, end -->
{{< tabs type="card" placement="top" >}}
{{% tab title="Tab 1" %}}Content for card style tab 1{{% /tab %}}
{{% tab title="Tab 2" %}}Content for card style tab 2{{% /tab %}}
{{% tab title="Tab 3" %}}Content for card style tab 3{{% /tab %}}
{{< /tabs >}}
### Segment
{{< tabs type="segment" >}}
{{% tab title="Tab 1" %}}Content for segment style tab 1{{% /tab %}}
{{% tab title="Tab 2" %}}Content for segment style tab 2{{% /tab %}}
{{% tab title="Tab 3" %}}Content for segment style tab 3{{% /tab %}}
{{< /tabs >}}
## Nested Tabs
{{< tabs defaultTab=0 >}}
{{% tab title="Outer Tab 1" %}}
This is the first outer tab with simple content.
**Features:**
- Basic text content
- No nested components
- Simple layout
{{% /tab %}}
{{% tab title="Outer Tab 2" %}}
This outer tab contains nested tabs inside:
{{< tabs type="pill" defaultTab=1 >}}
{{% tab title="Inner A" %}}
Nested tab A content with **bold text** and _italic text_.
```javascript
console.log('Hello from nested tab A!')
```
{{% /tab %}}
{{% tab title="Inner B" %}}
Nested tab B content with a list:
1. First item
2. Second item
3. Third item
> This is a blockquote inside a nested tab.
{{% /tab %}}
{{% tab title="Inner C" %}}
Nested tab C with a table:
| Feature | Status | Notes |
| :--------- | :----- | :--------------------- |
| Responsive | ✅ | Works on all devices |
| Accessible | ✅ | Screen reader friendly |
| Fast | ✅ | Optimized performance |
{{% /tab %}}
{{< /tabs >}}
{{% /tab %}}
{{% tab title="Outer Tab 3" %}}
This tab contains vertical nested tabs:
{{< tabs type="card" placement="end" >}}
{{% tab title="Vertical A" %}}
Content for vertical nested tab A.
- Feature 1
- Feature 2
- Feature 3
{{% /tab %}}
{{% tab title="Vertical B" %}}
Content for vertical nested tab B.
```css
.example {
color: #333;
background: #f5f5f5;
padding: 1rem;
}
```
{{% /tab %}}
{{< /tabs >}}
{{% /tab %}}
{{< /tabs >}}
## Others
### Mermaid Diagram inside Tabs
{{< tabs >}}
{{% tab title="Flowchart" %}}
```mermaid
flowchart TD
A[Start] --> B{Is it?}
B -->|Yes| C[OK]
C --> D[Rethink]
D --> B
B ---->|No| E[End]
```
{{% /tab %}}
{{% tab title="Gantt Chart" %}}
```mermaid
gantt
title A Gantt Diagram
dateFormat YYYY-MM-DD
section Section
A task :a1, 2014-01-01, 30d
Another task :after a1 , 20d
section Another
Task in sec :2014-01-12 , 12d
another task : 24d
```
{{% /tab %}}
{{< /tabs >}}
### File Tree inside Tabs
{{< tabs >}}
{{% tab title="File Tree Shortcode" %}}
{{< file-tree >}}
[[filetree]]
name = "src"
type = "dir"
[[filetree.children]]
name = "index.ts"
type = "file"
[[filetree]]
name = "README.md"
type = "file"
{{< /file-tree >}}
{{% /tab %}}
{{% tab title="File Tree Code Block" %}}
```file-tree
[[filetree]]
name = "src"
type = "dir"
[[filetree.children]]
name = "index.ts"
type = "file"
[[filetree]]
name = "README.md"
type = "file"
```
{{% /tab %}}
{{< /tabs >}}
### MathJax inside tabs
{{< tabs >}}
{{% tab title="Inline" %}}
$c = \pm\sqrt{a^2 + b^2}$ and \(f(x)=\int_{-\infty}^{\infty} \hat{f}(\xi) e^{2 \pi i \xi x} d \xi\)
{{% /tab %}}
{{% tab title="Block" %}}
$$ x = {-b \pm \sqrt{b^2-4ac} \over 2a} $$
\[ f(a) = \frac{1}{2\pi i} \oint\frac{f(z)}{z-a}dz \]
{{% /tab %}}
{{< /tabs >}}
-57
View File
@@ -1,57 +0,0 @@
---
title: Task List Rendering Test
date: 2026-02-28T08:54:02+08:00
collections:
- Tests
categories:
- Markdown
tags:
- Task List
---
This post tests the rendering of task lists in Markdown.
<!--more-->
## Basic Task Lists
- [ ] Unchecked Task
- [x] Checked Task
- Regular list item
## Extended Task Lists (Custom Icons)
- [-] Cancelled Task
- [/] In Progress Task
- [<] Scheduled Task
- [>] Rescheduled Task
- [!] Important Task
- [!x] Important Checked Task
- [?] Question Task
- Regular list item
## Nested Task Lists (Bug Fix Verification)
- [ ] Parent Task 1
- [ ] Child Task 1.1
- [x] Child Task 1.2
- Regular list item
- [/] Parent Task 2
- Regular list item
- [ ] Child Task 2.1
- [x] Grandchild Task 2.1.1
- [-] Grandchild Task 2.1.2
- [<] Scheduled Task
- [>] Rescheduled Task
- [!] Important Task
- [!x] Important Checked Task
- [?] Question Task
## Mixed Content in List Items
- [ ] Task with **bold** and _italic_ text
- [x] Task with `inline code`
- [ ] Task with [some link](https://github.com/hugo-fixit/FixIt)
- [ ] Multi-line task
that spans across multiple lines
and still renders correctly as a single list item.
-38
View File
@@ -1,38 +0,0 @@
- name: my-project
type: dir
children:
- name: src
type: dir
children:
- name: index.ts
type: file
- name: components
type: dir
children:
- name: Header.tsx
type: file
- name: Footer.tsx
type: file
- name: utils
type: dir
children:
- name: helper.ts
type: file
- name: validator.ts
type: file
- name: public
type: dir
children:
- name: favicon.ico
type: file
- name: images
type: dir
children:
- name: logo.png
type: file
- name: package.json
type: file
- name: README.md
type: file
- name: tsconfig.json
type: file
-78
View File
@@ -1,78 +0,0 @@
# -------------------------------------------------------------------------------------
# Hugo Configuration
# See: https://gohugo.io/configuration/all/
# -------------------------------------------------------------------------------------
title = "FixIt TEST"
baseURL = "https://demo.fixit.lruihao.cn/test/"
ignoreLogs = [
"warning-file-tree",
"warning-encryption"
]
defaultContentLanguage = "en"
# test for multilingual support
[languages]
[languages.en]
locale = "en"
label = "English"
# [todo] 优化中文排版
# [languages.zh-cn]
# locale = "zh-CN"
# label = "简体中文"
[languages.ar]
direction = "rtl"
locale = "ar"
label = "العربية"
[permalinks]
[permalinks.page]
posts = "/units/:slugorcontentbasename"
[permalinks.section]
posts = "/units/"
[markup]
_merge = "shallow"
[outputs]
_merge = "shallow"
[taxonomies]
_merge = "shallow"
# -------------------------------------------------------------------------------------
# Theme Core Configuration
# See: https://fixit.lruihao.cn/docs/getting-started/configuration/params/
# -------------------------------------------------------------------------------------
[params]
version = "1.0.X"
collection_list = true
collection_navigation = true
[params.home.profile]
enable = true
avatar_url = "/images/fixit-test.png"
[params.social]
[params.social.github]
id = "hugo-fixit"
weight = 2
[params.social.twitter]
id = "lruihao"
weight = 1
# for twitter cards
# site = "hugo-fixit"
[params.author]
name = "Lruihao"
email = ""
link = "https://lruihao.cn"
avatar = "https://lruihao.cn/images/avatar.jpg"
-8
View File
@@ -1,8 +0,0 @@
{
"name": "@hugo-fixit/test",
"private": true,
"scripts": {
"build": "hugo --themesDir ../.. --theme . --gc --minify --logLevel info",
"dev": "hugo server --themesDir ../.. --theme . -D --disableFastRender --navigateToChanged --ignoreCache -O"
}
}
+8 -6
View File
@@ -28,7 +28,7 @@ comment: false
Comment like this:
````markdown {mode=mac}
````markdown
```yaml
- nickname: <your nickname>
avatar: <your avatar>
@@ -37,8 +37,10 @@ Comment like this:
```
````
> [!NOTE]
>
> 1. If you want to exchange link, please leave a comment as the above format. (personal non-commercial blogs / websites only)
> 2. :(fa-solid fa-exclamation-triangle): Website failure, stop maintenance and improper content may be unlinked!
> 3. Those websites that do not respect other people's labor achievements, reprint without source, or malicious acts, please do not come to exchange.
{{< admonition info "Notice" true >}}
1. If you want to exchange link, please leave a comment as the above format. (personal non-commercial blogs / websites only)
2. :(fa-solid fa-exclamation-triangle): Website failure, stop maintenance and improper content may be unlinked!
3. Those websites that do not respect other people's labor achievements, reprint without source, or malicious acts, please do not come to exchange.
{{< /admonition >}}
+18 -6
View File
@@ -4,28 +4,40 @@ subtitle:
date: {{ .Date }}
slug: {{ substr .File.UniqueID 0 7 }}
draft: true
author:
name:
link:
email:
avatar:
description:
keywords:
license:
comment: false
weight: 0
categories:
- draft
collections:
- draft
tags:
- draft
categories:
- draft
hiddenFromHomePage: false
hiddenFromSearch: false
hiddenFromRelated: false
hiddenFromFeed: false
summary:
resources:
- name: featured-image
src: featured-image.jpg
- name: featured-image-preview
src: featured-image-preview.jpg
toc: true
math: false
lightgallery: false
password:
message:
repost:
enable: false
enable: true
url:
# See: https://fixit.lruihao.cn/docs/content-management/front-matter/
# See details front matter: https://fixit.lruihao.cn/documentation/content-management/introduction/#front-matter
---
<!--more-->
+23 -8
View File
@@ -4,25 +4,40 @@ subtitle:
date: {{ .Date }}
slug: {{ substr .File.UniqueID 0 7 }}
draft: true
author:
name:
link:
email:
avatar:
description:
keywords:
license:
comment: false
weight: 0
categories:
- draft
collections:
- draft
tags:
- draft
categories:
- draft
hiddenFromHomePage: false
hiddenFromSearch: false
hiddenFromRelated: false
hiddenFromFeed: false
summary:
featured_image:
featured_image_preview:
resources:
- name: featured-image
src: featured-image.jpg
- name: featured-image-preview
src: featured-image-preview.jpg
toc: true
math: false
lightgallery: false
password:
message:
repost:
enable: false
enable: true
url:
# See: https://fixit.lruihao.cn/docs/content-management/front-matter/
# See details front matter: https://fixit.lruihao.cn/documentation/content-management/introduction/#front-matter
---
<!--more-->
-2
View File
@@ -2,6 +2,4 @@
title: {{ T "assets.search" }}
layout: search
date: {{ .Date }}
description:
keywords:
---
+64
View File
@@ -0,0 +1,64 @@
@import "../../lib/normalize/normalize";
html {
font-family: $global-font-family;
font-weight: $global-font-weight;
font-display: swap;
font-size: $global-font-size;
line-height: $global-line-height;
width: 100%;
scroll-behavior: smooth;
overflow: overlay;
}
@media screen and (prefers-reduced-motion: reduce) {
html {
scroll-behavior: auto;
}
}
::selection {
background-color: $selection-color;
[data-theme='dark'] & {
background-color: $selection-color-dark;
}
}
body {
background-color: $global-background-color;
color: $global-font-color;
@include overflow-wrap(break-word);
[data-theme='dark'] & {
color: $global-font-color-dark;
background-color: $global-background-color-dark;
}
}
iframe {
border: 0;
@include border-radius($global-border-radius);
}
[role='button'] {
cursor: pointer;
}
summary {
cursor: pointer;
}
abbr[title] {
cursor: help;
text-decoration-skip-ink: none;
}
@include link(true, true);
@import '../_partials/scrollbar';
@import '../_partials/mask';
@import '../_partials/img';
@import '../_partials/icon';
@import '../_partials/details';
@import '../_partials/widgets';
+49
View File
@@ -0,0 +1,49 @@
.breadcrumb-container {
padding-inline: 1rem;
font-size: 0.75rem;
background-color: $global-background-color;
@include z-index(1);
@extend .print-d-none;
[data-theme='dark'] & {
background-color: $global-background-color-dark;
}
&.sticky {
position: sticky;
top: $header-height;
}
.breadcrumb {
display: flex;
flex-wrap: wrap;
padding: 0.5rem 0;
margin: 0 auto;
list-style: none;
border-bottom: 1px inset $global-border-color;
@extend %page-style;
[data-theme='dark'] & {
border-bottom-color: $global-border-color-dark;
}
.breadcrumb-item {
display: flex;
+ .breadcrumb-item::before {
content: attr(data-separator);
display: inline-block;
padding-inline: 0.5rem;
color: $global-font-secondary-color;
[data-theme='dark'] & {
color: $global-font-secondary-color-dark;
}
}
&.active {
color: var(--#{$prefix}secondary);
}
}
}
}
+56
View File
@@ -0,0 +1,56 @@
// ==============================
// Common Styles
// 常用样式
// ==============================
.text-truncate {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.text-start {
text-align: left !important;
}
.text-end {
text-align: right !important;
}
.text-center {
text-align: center !important;
}
.d-none {
display: none !important;
}
.ms-1,
.mx-1 {
margin-left: 0.25em !important;
}
.me-1,
.mx-1 {
margin-right: 0.25em !important;
}
.ps-1,
.px-1 {
padding-left: 0.25em !important;
}
.pe-1,
.px-1 {
padding-right: 0.25em !important;
}
@each $color, $value in $theme-colors {
.text-#{$color} {
color: var(--#{$prefix}#{$color}) !important;
}
}
@each $key, $value in $orders {
.order-#{$key} {
order: #{$value} !important;
}
}
.variant-numeric {
font-variant-numeric: tabular-nums lining-nums;
}
@@ -1,11 +1,10 @@
@use "core/mixins" as *;
footer {
height: auto;
width: 100%;
text-align: center;
line-height: 1.25rem;
padding: 1rem 0;
@extend .print-d-none;
.footer-container {
display: flex;
@@ -17,53 +16,44 @@ footer {
.footer-divider:not(:first-child)::before {
content: '|';
margin-inline: 0.25rem;
}
.hugo-icon,
.fixit-icon,
.animate-icon {
@include dark-mode {
filter: invert(1) hue-rotate(0.5turn) opacity(0.6);
}
margin-left: 0.25rem;
margin-right: 0.25rem;
}
.animate-icon {
color: light-dark(#e01846, #ff5f7a);
color: #dc143c;
animation: icon-animate 1.33s ease-in-out infinite;
}
}
@include media('xs') {
font-size: 0.618rem;
.run-times {
font-variant-numeric: tabular-nums lining-nums;
}
}
}
@include media('print') {
display: none !important;
}
@include blur;
}
@keyframes icon-animate {
0%,
100% {
scale: 1;
@include transform(scale(1));
}
10%,
30% {
scale: 0.9;
@include transform(scale(0.9));
}
20%,
40%,
60%,
80% {
scale: 1.1;
@include transform(scale(1.1));
}
50%,
70% {
scale: 1.1;
@include transform(scale(1.1));
}
}
+665
View File
@@ -0,0 +1,665 @@
header {
width: 100%;
background-color: $header-background-color;
@include z-index(2);
@include transition(box-shadow 0.3s ease);
@extend .print-d-none;
[data-theme='dark'] & {
background-color: $header-background-color-dark;
}
&:hover {
@include box-shadow(0 0 1.5rem 0 rgba(0, 0, 0, 0.1));
[data-theme='dark'] & {
@include box-shadow(0 0 1.5rem 0 rgba(255, 255, 255, 0.1));
}
}
}
.header-wrapper {
display: flex;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
width: 100%;
}
.header-title {
font-family: $header-title-font-family;
font-weight: bold;
margin-right: 0.5rem;
min-width: 10%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
@include flex(10);
.logo {
min-height: 1.5em;
height: 1.5em;
vertical-align: middle;
width: auto;
}
.header-title-text {
margin-left: 0.25rem;
margin-right: 0.25rem;
}
.header-subtitle {
margin-left: 0.25rem;
font-size: 0.6em;
}
}
.menu {
margin: 0;
padding: 0;
.menu-item-divider {
list-style: none;
margin: 0.25rem 0.5rem;
height: 1px;
background-color: $menu-border-color;
[data-theme='dark'] & {
background-color: $menu-border-color-dark;
}
}
.menu-item {
list-style: none;
& .dropdown-icon {
margin-left: 0.25rem;
font-size: .875em;
color: $global-font-color;
[data-theme='dark'] & {
color: $global-font-color-dark;
}
&.open::before {
content: "\f078";
}
}
&.active {
>.menu-link,
>.nested-item>.menu-link {
font-weight: bold;
color: $menu-active-color;
[data-theme='dark'] & {
color: $menu-active-color-dark;
}
}
}
.menu-link[href="javascript:void(0);"] {
color: inherit;
}
.menu-link i {
@include transform(perspective(1rem));
@include transition(transform 0.4s ease);
}
.menu-link:hover i {
@include transform(perspective(1rem) translateZ(0.2rem));
}
&.language-switch,
&.theme-switch {
cursor: pointer;
}
}
}
.menu .search {
position: relative;
input {
color: transparent;
box-sizing: border-box;
height: 2.5rem;
width: 1.25rem;
@include border-radius(0.5rem);
border: none;
outline: none;
background-color: transparent;
vertical-align: baseline !important;
@include transition(width 0.3s ease);
}
@include placeholder(transparent);
.search-button {
margin: 0;
position: absolute;
left: auto;
right: 1rem;
}
.search-toggle {
left: 0.5rem;
right: auto;
#header-desktop.open & {
left: 1rem;
}
}
.search-loading {
display: none;
}
.search-clear {
display: none;
}
.open &,
&.mobile {
input {
color: $global-font-color;
background-color: $search-background-color;
padding: 0 2rem 0 2rem;
}
[data-theme='dark'] & {
input {
color: $global-font-color-dark;
background-color: $search-background-color-dark;
}
@include placeholder($global-font-secondary-color-dark);
}
@include placeholder($global-font-secondary-color);
.search-button {
color: $global-font-secondary-color;
[data-theme='dark'] & {
color: $global-font-secondary-color-dark;
}
}
.search-clear:hover {
color: #ff6b6b;
}
.search-toggle:hover {
cursor: default;
}
}
}
.theme-switch {
i {
@include transform(rotate(225deg));
@include transition(transform 0.4s ease);
}
&:hover i {
@include transform(rotate(45deg));
}
}
#header-desktop {
display: block;
position: sticky;
top: 0;
height: $header-height;
line-height: $header-height;
box-sizing: border-box;
[data-header-desktop='normal'] & {
position: static;
}
nav {
overflow: hidden;
white-space: nowrap;
}
.header-wrapper {
// use css native function to calculate max value
padding: 0 2rem 0 MAX(10vh, $header-height);
height: 100%;
&[data-github-corner='right'] {
padding-right: $header-height;
}
.header-title {
font-size: $header-title-font-size;
height: 100%;
}
.menu {
display: flex;
flex-direction: row;
flex-wrap: nowrap;
float: right;
>.menu-item {
&:hover .sub-menu {
display: block;
@include transform(translateX(-0.5rem));
}
&.language-switch:hover .sub-menu {
@include transform(translateX(calc(1.75rem - 100%)));
}
}
.menu-item {
padding: 0 0.5rem;
&.delimiter {
width: 0;
margin: 0.125rem 0.25rem;
padding: 0;
border-left: 1px dashed lighten($global-font-secondary-color, 15%);
[data-theme='dark'] & {
border-left-color: darken($global-font-secondary-color-dark, 15%);
}
}
}
.sub-menu {
position: absolute;
margin: 0;
padding: 0.25rem 0;
display: none;
top: calc(#{$header-height} - 0.75rem);
border-radius: $global-border-radius;
border: 1px solid $menu-border-color;
background-color: $header-background-color;
max-height: 60vh;
overflow-y: auto;
@include transition(box-shadow 0.3s ease);
@include box-shadow(0 0 1.5rem 0 rgba(0, 0, 0, 0.1));
[data-theme='dark'] & {
background-color: $header-background-color-dark;
border-color: $menu-border-color-dark;
@include box-shadow(0 0 1.5rem 0 rgba(255, 255, 255, 0.1));
}
.menu-item {
height: $submenu-height;
line-height: $submenu-height;
max-width: 15rem;
white-space: nowrap;
text-overflow: ellipsis;
overflow-x: hidden;
}
}
}
}
&.open .header-wrapper .menu .menu-item.search {
input {
width: 24rem;
}
}
}
#header-mobile {
display: none;
position: sticky;
top: 0;
min-height: $header-height;
line-height: $header-height;
[data-header-mobile='normal'] & {
position: static;
}
.header-container {
padding: 0;
margin: 0;
.header-wrapper {
padding: 0 1rem;
font-size: 1.125rem;
@include transition(margin-top 0.3s ease);
.header-title {
font-size: $header-title-font-size;
max-width: 80%;
}
.menu-toggle {
line-height: 4rem;
cursor: pointer;
@include transition(width 0.3s ease);
span {
display: block;
background: $global-font-color;
width: 1.5rem;
height: 2px;
@include border-radius(3px);
@include transition(all 0.3s ease-in-out);
[data-theme='dark'] & {
background: $global-font-color-dark;
}
}
span:nth-child(1) {
margin-bottom: 0.5rem;
}
span:nth-child(3) {
margin-top: 0.5rem;
}
&.active {
span:nth-child(1) {
@include transform(rotate(45deg) translate(0.4rem, 0.5rem));
}
span:nth-child(2) {
opacity: 0;
}
span:nth-child(3) {
@include transform(rotate(-45deg) translate(0.4rem, -0.5rem));
}
}
}
}
.menu {
background: $header-background-color;
border-top: 2px solid $global-border-color;
display: none;
overflow-y: overlay;
max-height: 70vh;
@include box-shadow(0 0.125rem 0.25rem rgba(0, 0, 0, 0.1));
@include scrollbar-width(none, 0);
[data-theme='dark'] & {
background: $header-background-color-dark;
border-top-color: $global-border-color-dark;
@include box-shadow(0 0.125rem 0.25rem rgba(255, 255, 255, 0.1));
}
.search-wrapper {
display: flex;
justify-content: space-between;
align-items: center;
box-sizing: border-box;
padding: ($header-height - 2.5rem) / 2 1rem;
line-height: 2.5rem;
position: sticky;
top: 0;
background-color: $header-background-color;
@include z-index(0, 50);
[data-theme='dark'] & {
background-color: $header-background-color-dark;
}
}
.search {
flex-grow: 10;
.algolia-autocomplete,
input {
width: 100%;
}
}
.search-loading,
.search-clear {
right: 0.5rem;
}
.search-button {
top: 0;
}
.search-cancel {
display: none;
margin-left: 0.75rem;
}
.menu-item {
display: block;
position: relative;
line-height: 2.5rem;
padding: 0 1rem;
&:not(.menu-system):hover {
background-color: lighten($global-font-secondary-color, 24%);
[data-theme='dark'] & {
background-color: darken($global-font-secondary-color-dark, 24%);
}
}
.menu-link {
display: block;
white-space: nowrap;
text-overflow: ellipsis;
overflow-x: hidden;
@include flex(4);
}
& .nested-item {
display: flex;
justify-content: space-between;
align-items: center;
.menu-link {
max-width: 80%;
}
}
}
.menu-system {
display: flex;
justify-content: center;
gap: 0.25rem;
position: sticky;
bottom: 0;
line-height: 2.5rem;
padding: 0 1rem;
background-color: $header-background-color;
[data-theme='dark'] & {
background-color: $header-background-color-dark;
}
.menu-system-item {
padding-inline: 0.5rem;
}
.language-switch {
position: relative;
.language-select {
position: absolute;
opacity: 0;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
}
}
.sub-menu {
padding-left: 0;
display: none;
&.open {
display: block;
}
.menu-item:hover {
background-color: lighten($global-font-secondary-color, 20%);
[data-theme='dark'] & {
background-color: darken($global-font-secondary-color-dark, 20%);
}
}
}
&.active {
display: block;
}
}
}
&.open {
.header-wrapper {
margin-top: -$header-height;
}
.menu {
padding-top: 0;
border-top: none;
.menu-item {
display: none;
}
.search-cancel {
display: inline;
}
}
}
}
.search-dropdown {
position: fixed;
top: $header-height;
@include z-index(2);
@include box-shadow(0 0.125rem 0.25rem rgba(0, 0, 0, 0.1));
[data-theme='dark'] & {
@include box-shadow(0 0.125rem 0.25rem rgba(255, 255, 255, 0.1));
}
&.desktop {
right: 2rem;
width: 30rem;
}
&.mobile {
right: 0;
width: 100%;
}
.dropdown-menu {
right: 0 !important;
background-color: $global-background-color;
[data-theme='dark'] & {
background-color: $global-background-color-dark;
}
.suggestions {
overflow-y: auto;
max-height: calc(100vh - #{$header-height});
.suggestion {
padding: 0.75rem 1rem;
.suggestion-title {
display: inline-block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 1rem;
font-weight: bold;
max-width: 75%;
}
.suggestion-date {
font-size: 0.875rem;
float: right;
text-align: right;
color: $global-font-secondary-color;
[data-theme='dark'] & {
color: $global-font-secondary-color-dark;
}
}
.suggestion-context {
line-height: 1.25rem;
@include box(vertical);
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
@include overflow-wrap(break-word);
color: $global-font-secondary-color;
[data-theme='dark'] & {
color: $global-font-secondary-color-dark;
}
}
em {
font-style: normal;
background-color: $selection-color;
[data-theme='dark'] & {
background-color: $selection-color-dark;
}
}
&.cursor {
background: darken($code-background-color, 5%);
[data-theme='dark'] & {
background: lighten($code-background-color-dark, 5%);
}
}
&:hover {
cursor: pointer;
}
}
}
.search-empty {
padding: 1rem;
text-align: center;
.search-query {
font-weight: bold;
[data-theme='dark'] & {
color: #ddd;
}
}
}
.search-footer {
padding: 0.5rem 1rem;
float: right;
font-size: 0.8rem;
color: $global-font-secondary-color;
[data-theme='dark'] {
color: $global-font-secondary-color-dark;
}
@include link(false, false);
a {
font-size: 1rem;
}
}
}
}
+41
View File
@@ -0,0 +1,41 @@
/** Layout **/
.wrapper {
display: flex;
flex-direction: column;
min-height: 100vh;
width: 100%;
main {
flex: 1 0 auto;
aside {
flex: 1;
padding: 0.5rem;
&:not(:has(~ aside)) {
display: none;
}
}
&.container {
display: flex;
align-items: flex-start;
justify-content: center;
padding-inline: 1rem;
gap: 0.5rem;
&.container-reverse {
flex-direction: row-reverse;
}
&:has(.home:not(.posts)) {
align-items: center;
}
}
}
}
@import "_header";
@import "_breadcrumb";
@import "_footer";
@import "_pagination";
+162
View File
@@ -0,0 +1,162 @@
@media only screen and (min-width: 1441px) {
%page-style {
width: ROUND(60%, 2px);
[data-page-style='wide'] & {
width: ROUND(64%, 2px);
}
[data-page-style='narrow'] & {
max-width: 800px;
}
}
}
@media only screen and (max-width: 1440px) {
%page-style {
width: ROUND(56%, 2px);
[data-page-style='wide'] & {
width: ROUND(60%, 2px);
}
}
}
@media only screen and (max-width: 1200px) {
%page-style {
width: ROUND(52%, 2px);
[data-page-style='wide'] & {
width: ROUND(56%, 2px);
}
}
#header-desktop .header-wrapper {
padding-right: 1rem;
}
.search-dropdown.desktop {
right: 1rem;
}
}
@media only screen and (max-width: 960px) {
%page-style {
width: ROUND(80%, 2px) !important;
}
aside {
display: none !important;
}
#toc-static {
display: block;
}
#header-desktop .header-wrapper {
padding-left: 1rem;
}
}
@media only screen and (min-width: 681px) {
.d-none-desktop {
display: none;
}
.breadcrumb-container.sticky {
body:not([data-header-desktop='sticky']) & {
top: 0;
}
// adjust the scroll margin top of the content anchors on the page
body:not([data-header-desktop='auto']) &+.container .content [id] {
scroll-margin-top: calc(var(--#{$prefix}scroll-mt) + var(--#{$prefix}breadcrumb-height));
}
}
[data-header-desktop='normal'] .page .content [id] {
--#{$prefix}scroll-mt: #{$global-scroll-margin-top};
}
}
@media only screen and (max-width: 680px) {
#header-desktop {
display: none;
}
#header-mobile {
display: block;
}
.d-none-mobile {
display: none !important;
}
.breadcrumb-container.sticky {
body:not([data-header-mobile='sticky']) & {
top: 0;
}
// adjust the scroll margin top of the content anchors on the page
body:not([data-header-mobile='auto']) &+.container .content [id] {
scroll-margin-top: calc(var(--#{$prefix}scroll-mt) + var(--#{$prefix}breadcrumb-height));
}
}
[data-header-mobile='normal'] .page .content [id] {
--#{$prefix}scroll-mt: #{$global-scroll-margin-top};
}
%page-style {
width: 100% !important;
}
.page {
.categories-card,
.collections-card {
.card-item {
width: 100%;
}
}
}
footer {
.footer-container {
font-size: 0.618rem;
}
}
.pagination .page-item {
margin: 0 5px;
}
}
@media only print {
@page {
size: A4 portrait;
margin: 1.27cm;
}
.page {
width: 100% !important;
padding-top: 0 !important;
&.single {
.single-title,
.single-subtitle,
.post-meta {
text-align: center;
}
}
h1:not(.single-title),
.page-break-before {
page-break-before: always;
}
.page-break-after {
page-break-after: always;
}
}
.print-d-none {
display: none !important;
}
}
@@ -1,6 +1,3 @@
@use "core/functions" as *;
@use "core/mixins" as *;
.pagination {
display: flex;
flex-direction: row;
@@ -13,12 +10,16 @@
a {
font-size: 0.8rem;
color: fi-var(pagination-link-color);
color: $pagination-link-color;
letter-spacing: 0.1rem;
font-weight: 700;
padding: 5px 5px;
text-decoration: none;
transition: 0.3s;
@include transition(0.3s);
[data-theme='dark'] & {
color: $pagination-link-color-dark;
}
}
li {
@@ -33,7 +34,11 @@
}
&:hover a {
color: fi-var(pagination-link-hover-color);
color: $pagination-link-hover-color;
}
[data-theme='dark'] &:hover a {
color: $pagination-link-hover-color-dark;
}
&::before,
@@ -42,9 +47,14 @@
content: '';
width: 0;
height: 3px;
background: fi-var(pagination-link-hover-color);
background: $pagination-link-hover-color;
@include transition(0.3s);
bottom: 0px;
transition: 0.3s;
}
[data-theme='dark'] &::before,
[data-theme='dark'] &::after {
background: $pagination-link-hover-color-dark;
}
&::before {
@@ -64,7 +74,11 @@
&.active {
a {
color: fi-var(pagination-link-hover-color);
color: $pagination-link-hover-color;
}
[data-theme='dark'] & a {
color: $pagination-link-hover-color-dark;
}
&::before,
@@ -72,9 +86,5 @@
width: 50%;
}
}
@include media('xs') {
margin: 0 5px;
}
}
}
+68
View File
@@ -0,0 +1,68 @@
/* Resolve style conflicts between third-party plugins */
@keyframes #{$prefix}pulse {
from {
@include transform(scale3d(1, 1, 1));
}
50% {
@include transform(scale3d(1.05, 1.05, 1.05));
}
to {
@include transform(scale3d(1, 1, 1));
}
}
.animate__pulse {
-webkit-animation-name: #{$prefix}pulse !important;
animation-name: #{$prefix}pulse !important;
}
/**
* After the CSS round() function exceeds 90% browser support in the future, this code can be removed
* See https://caniuse.com/mdn-css_types_round
*/
@supports not (width: ROUND(60%, 2px)) {
@media only screen and (min-width: 1441px) {
%page-style {
width: 60%;
[data-page-style='wide'] & {
width: 64%;
}
[data-page-style='narrow'] & {
max-width: 800px;
}
}
}
@media only screen and (max-width: 1440px) {
%page-style {
width: 56%;
[data-page-style='wide'] & {
width: 60%;
}
}
}
@media only screen and (max-width: 1200px) {
%page-style {
width: 52%;
[data-page-style='wide'] & {
width: 56%;
}
}
}
@media only screen and (max-width: 960px) {
%page-style {
width: 80% !important;
}
}
@media only screen and (max-width: 680px) {
%page-style {
width: 100% !important;
}
}
}
+42
View File
@@ -0,0 +1,42 @@
:root {
// Note: Custom variable values only support SassScript inside `#{}`.
// TODO migrate SCSS variables to CSS variables
--#{$prefix}global-font-color: #{$global-font-color};
--#{$prefix}global-border-color: #{$global-border-color};
// Theme colors variables
@each $color, $value in $theme-colors {
--#{$prefix}#{$color}: #{$value};
}
// Scroll margin top and Stack sticky top related
--#{$prefix}scroll-mt: calc(#{$header-height} + #{$global-scroll-margin-top});
// Set breadcrumb height to 0px if breadcrumb is disabled
--#{$prefix}breadcrumb-height: 0px;
// hr style
--#{$prefix}hr-background-color: #{darken($global-border-color, 5%)};
--#{$prefix}hr-before-color: #{lighten($single-link-hover-color, 4%)};
// Scrollbar related variables
--#{$prefix}scrollbar-thumb-color: #{$scrollbar-color};
--#{$prefix}scrollbar-thumb-hover-color: #{$scrollbar-hover-color};
--#{$prefix}scrollbar-track-color: transparent;
--#{$prefix}scrollbar-width: thin;
--#{$prefix}scrollbar-width-legacy: 12px;
}
// Dark theme
[data-theme=dark] {
--#{$prefix}global-font-color: #{$global-font-color-dark};
--#{$prefix}global-border-color: #{$global-border-color-dark};
@each $color, $value in $theme-colors {
--#{$prefix}#{$color}: #{darken($value, 5%)};
}
--#{$prefix}hr-background-color: #{lighten($global-border-color-dark, 5%)};
--#{$prefix}hr-before-color: #{darken($global-link-hover-color-dark, 4%)};
}
+4
View File
@@ -0,0 +1,4 @@
// ==============================
// Custom style
// 自定义样式
// ==============================
+5
View File
@@ -0,0 +1,5 @@
@mixin blur {
.blur & {
@include filter(blur(1.5px));
}
}
+107
View File
@@ -0,0 +1,107 @@
@mixin border-radius($value) {
-webkit-border-radius: $value;
-moz-border-radius: $value;
border-radius: $value;
}
@mixin box-shadow($values...) {
-webkit-box-shadow: $values;
box-shadow: $values;
}
@mixin transition($values...) {
-webkit-transition: $values;
-moz-transition: $values;
-o-transition: $values;
transition: $values;
}
@mixin transform($value) {
-webkit-transform: $value;
-ms-transform: $value;
-o-transform: $value;
transform: $value;
}
@mixin filter($value) {
-webkit-filter: $value;
filter: $value;
}
@mixin flex($value) {
-webkit-flex: $value;
flex: $value;
}
@mixin box($orient) {
display: -moz-box;
display: -webkit-box;
display: box;
-webkit-box-orient: $orient;
-moz-box-orient: $orient;
box-orient: $orient;
}
@mixin placeholder($color) {
input::-webkit-input-placeholder {
color: $color;
}
input:-moz-placeholder {
color: $color;
}
input::-moz-placeholder {
color: $color;
}
input:-ms-input-placeholder {
color: $color;
}
input::placeholder {
color: $color;
}
}
@mixin max-content($property) {
#{$property}: -webkit-max-content;
#{$property}: -moz-max-content;
#{$property}: intrinsic;
#{$property}: max-content;
}
@mixin tab-size($value) {
-moz-tab-size: $value;
-o-tab-size: $value;
tab-size: $value;
}
@mixin appearance($value) {
-moz-appearance: $value;
-webkit-appearance: $value;
}
@mixin overflow-wrap($value) {
word-wrap: $value;
overflow-wrap: $value;
}
@mixin line-break($value) {
-webkit-line-break: $value;
-ms-line-break: $value;
line-break: $value;
}
@mixin object-fit($value) {
-o-object-fit: $value;
object-fit: $value;
font-family: 'object-fit: #{$value};';
}
@mixin user-select($value) {
-webkit-user-select: $value !important;
-moz-user-select: $value !important;
user-select: $value !important;
}
+15
View File
@@ -0,0 +1,15 @@
@mixin details-transition-open {
@include transition(max-height 0.2s cubic-bezier(0, 1, 0, 1) -0.1s);
}
@mixin details-transition-close {
@include transition(max-height 0.2s cubic-bezier(0.5, 0, 1, 0) 0s);
}
details {
&.center {
summary {
text-align: center;
}
}
}
+6
View File
@@ -0,0 +1,6 @@
@import '_compatibility';
@import '_link';
@import '_blur';
@import '_details';
@import '_scrollbar-width';
@import '_z-index';
+52
View File
@@ -0,0 +1,52 @@
/**
* Link mixin
* @param {Boolean} $light use global link color
* @param {Boolean} $dark use global link color dark
* @param {String} $decoration text-decoration, default none
*/
@mixin link($light, $dark, $decoration: none) {
a,
a::before,
a::after {
text-decoration: $decoration;
@if $light {
color: $global-link-color;
}
@else {
color: $single-link-color;
}
[data-theme='dark'] & {
@if $dark {
color: $global-link-color-dark;
}
@else {
color: $single-link-color-dark;
}
}
}
a:active,
a:hover {
@if $light {
color: $global-link-hover-color;
}
@else {
color: $single-link-hover-color;
}
[data-theme='dark'] & {
@if $dark {
color: $global-link-hover-color-dark;
}
@else {
color: $single-link-hover-color-dark;
}
}
}
}
+4
View File
@@ -0,0 +1,4 @@
@mixin scrollbar-width($width: thin, $widthLegacy: 12px) {
--#{$prefix}scrollbar-width: #{$width};
--#{$prefix}scrollbar-width-legacy: #{$widthLegacy};
}
+3
View File
@@ -0,0 +1,3 @@
@mixin z-index($level, $diff: 0) {
z-index: ($level * 100) + $diff;
}
+4
View File
@@ -0,0 +1,4 @@
// ==============================
// Override Variables
// 覆盖变量
// ==============================
+6
View File
@@ -0,0 +1,6 @@
#content-404 {
font-size: 1.8rem;
line-height: 3rem;
@include transform(translateY(30vh));
text-align: center;
}
@@ -1,6 +1,3 @@
// Archives page styles (section, taxonomy, term)
@use "sass:meta";
.archive {
.single-title {
padding: 1rem 0 0.5rem;
@@ -8,7 +5,7 @@
font-size: 1.6rem;
font-weight: bold;
line-height: 140%;
text-align: end;
text-align: right;
}
.single-subtitle {
@@ -16,7 +13,7 @@
font-size: 1.2rem;
font-weight: normal;
line-height: 100%;
text-align: end;
text-align: right;
}
.group-title {
@@ -25,6 +22,6 @@
margin-bottom: 1rem;
}
@include meta.load-css('terms');
@include meta.load-css('tags');
@import '../_partials/_archive/terms';
@import '../_partials/_archive/tags';
}
@@ -1,6 +1,3 @@
@use "core/functions" as *;
@use "core/mixins" as *;
.home {
.home-profile {
text-align: center;
@@ -13,13 +10,17 @@
width: 8rem;
height: auto;
margin: 0 auto;
transition: all 0.4s ease;
box-shadow: 0 0 0 0.3618em light-dark(rgba(0, 0, 0, 0.05), rgba(255, 255, 255, 0.05));
@include border-radius(full);
@include border-radius(100%);
@include box-shadow(0 0 0 0.3618em rgba(0, 0, 0, 0.05));
@include transition(all 0.4s ease);
[data-theme='dark'] & {
@include box-shadow(0 0 0 0.3618em rgba(255, 255, 255, 0.05));
}
&:hover {
position: relative;
translate: 0 -0.75rem;
@include transform(translateY(-0.75rem));
}
}
}
@@ -61,7 +62,11 @@
font-weight: normal;
margin: 0;
padding: 0.5rem;
color: fi-var(global-font-secondary-color);
color: $global-font-secondary-color;
[data-theme='dark'] & {
color: $global-font-secondary-color-dark;
}
}
}
}
@@ -76,20 +81,19 @@
}
.summary {
position: relative;
padding-block: 1rem;
color: fi-var(global-font-color);
color: var(--#{$prefix}global-font-color);
&:not(:last-of-type)::after {
content: '';
position: absolute;
width: 100%;
padding: 1.5px;
translate: 0 18px;
padding: 2px;
transform: translateY(18px);
background: repeating-linear-gradient(
135deg,
fi-var(global-border-color) 0px,
fi-var(global-border-color) 4px,
var(--#{$prefix}hr-background-color) 0px,
var(--#{$prefix}hr-background-color) 4px,
transparent 4px,
transparent 8px
);
@@ -105,19 +109,19 @@
aspect-ratio: auto 1000 / 420;
position: relative;
margin: 0.6rem auto;
transition: scale 0.4s ease;
@include transition(transform 0.4s ease);
img {
position: absolute;
width: 100%;
height: 100%;
inset-inline-start: 0;
left: 0;
top: 0;
object-fit: cover;
@include object-fit(cover);
}
&:hover {
scale: 1.01;
@include transform(scale(1.01));
}
}
@@ -129,12 +133,21 @@
.content {
margin-top: 0.3rem;
color: fi-var(global-font-tertiary-color);
color: $global-font-secondary-color;
[data-theme='dark'] & {
color: $global-font-secondary-color-dark;
}
@include link(false, true);
b,
strong {
color: fi-var(global-font-tertiary-color);
color: $global-font-secondary-color;
[data-theme='dark'] & {
color: $global-font-secondary-color-dark;
}
}
}
@@ -144,19 +157,17 @@
justify-content: space-between;
align-items: center;
font-size: 0.875rem;
@include link(false, false);
.post-tags {
padding: 0;
@include link(true, true);
.post-tag:not(:last-child)::after {
content: ',';
margin-inline-end: 0.25rem;
[dir="rtl"] & {
scale: -1 1;
}
margin-right: 0.25rem;
}
}
}
+19
View File
@@ -0,0 +1,19 @@
.page {
position: relative;
@extend %page-style;
.content {
[id] {
scroll-margin-top: var(--#{$prefix}scroll-mt);
}
}
@include blur;
}
@import '_single';
@import '_special';
@import '_archive';
@import '_home';
@import '_404';
@import '_offline';
+19
View File
@@ -0,0 +1,19 @@
#content-offline {
@include transform(translateY(30vh));
text-align: center;
.offline-title {
font-size: 3.6rem;
}
.offline-subtitle {
margin: 0.4rem 0;
font-size: 1rem;
font-weight: normal;
font-style: italic;
line-height: 100%;
color: #57606a;
}
.error-text {
font-size: 1.2rem;
}
}
+539
View File
@@ -0,0 +1,539 @@
@import '../_partials/_single/toc';
@import '../_partials/_single/fixit-decryptor';
@import '../_partials/_single/collections';
.single {
.single-title {
padding: 1rem 0 0.5rem;
margin: 0;
font-size: 1.6rem;
font-weight: bold;
line-height: 140%;
.icon-pin {
display: inline-block;
width: max-content;
transform: rotate(30deg);
margin-right: 0.25em;
color: var(--#{$prefix}danger);
}
.icon-repost {
display: inline-block;
width: max-content;
margin-right: 0.25em;
color: var(--#{$prefix}success);
}
}
.single-subtitle {
margin-block: 0 0.5rem;
font-size: 1.2rem;
font-weight: normal;
line-height: 1.15;
}
.post-meta {
font-size: 0.875rem;
color: $global-font-secondary-color;
.comment-visitors,
.comment-count {
@extend .print-d-none;
}
span {
display: inline-block;
}
[data-theme='dark'] & {
color: $global-font-secondary-color-dark;
}
@include link(false, true);
.author {
font-size: 1.05rem;
img.avatar {
width: 1.3rem;
height: 1.3rem;
border-radius: 50%;
vertical-align: text-bottom;
border: 0.25px solid $global-border-color;
box-sizing: border-box;
object-position: center;
@include object-fit(cover);
[data-theme='dark'] & {
border-color: $global-border-color-dark;
}
}
}
}
.featured-image {
margin: 1rem 0;
img {
display: block;
width: 100%;
max-width: 100%;
height: auto;
margin: 0 auto;
overflow: hidden;
}
}
#content[data-end-flag]:not([data-password])::after {
content: attr(data-end-flag);
display: block;
text-align: center;
color: $global-font-secondary-color;
font-size: 15px;
padding: 5px;
}
hr {
position: relative;
height: 1em;
margin-block: 1em;
background: linear-gradient(to right, var(--#{$prefix}hr-background-color) 50%, transparent 50%);
background-size: 10px 2px;
background-position: center;
background-repeat: repeat-x;
border: none;
&.awesome-hr {
&::before {
display: inline-block;
font-weight: 600;
font-family: 'Font Awesome 6 Free';
text-rendering: auto;
-webkit-font-smoothing: antialiased;
position: absolute;
left: 5%;
top: 50%;
transform: translateY(-50%);
z-index: 1;
color: var(--#{$prefix}hr-before-color);
content: '\f0c4';
font-size: 20px;
line-height: 1;
transition: left 1s ease-in-out, color 0.3s ease, border-color 0.3s ease;
}
&:hover::before {
left: calc(95% - 20px);
}
}
}
.content {
margin-block: 1rem;
> h1,
> h2 {
font-size: 1.5em;
padding-bottom: 0.3em;
border-bottom: 1px solid $global-border-color;
}
> h3 {
font-size: 1.25em;
}
> h4 {
font-size: 1em;
}
> h5 {
font-size: 0.875em;
}
> h6 {
font-size: 0.85em;
}
> .heading-element {
display: flex;
font-weight: bold;
line-height: 1.25;
margin-top: 1.5rem;
margin-bottom: 1rem;
[data-theme='dark'] & {
font-weight: bolder;
}
code {
padding: 0 .2em;
font-size: inherit;
}
&:hover,
&:target {
> .heading-mark {
opacity: 1;
}
}
> .heading-mark {
display: inline-flex;
align-items: center;
opacity: 0;
padding-inline: 0.5rem;
transition: all 0.2s ease-in-out;
@include link(false, false);
svg {
fill: currentColor;
}
}
}
p {
margin: 0.5rem 0;
}
b,
strong {
font-weight: bold;
[data-theme='dark'] & {
color: #ddd;
}
}
@include link(false, false);
a {
white-space: normal;
@include overflow-wrap(break-word);
[data-theme='dark'] & b,
[data-theme='dark'] & strong {
color: $single-link-color-dark;
}
}
[data-theme='dark'] a:hover b,
[data-theme='dark'] a:hover strong {
color: $single-link-hover-color-dark;
}
ul,
ol,
dl {
margin-block: 0.5em;
}
ul {
list-style-type: disc;
// Task lists
li[data-task] {
list-style: none;
margin-left: -1.5rem;
}
}
// Task lists
li[data-task] {
color: var(--#{$prefix}task-color);
.checkbox-icon {
margin-right: 0.25em;
color: var(--#{$prefix}checkbox-color);
}
}
li[data-task='x'],
li[data-task='-'] {
--#{$prefix}task-color: var(--#{$prefix}secondary);
text-decoration: line-through rgba(145, 145, 145, 0.6);
}
li[data-task='x'] {
--#{$prefix}checkbox-color: var(--#{$prefix}primary);
}
li[data-task='-'] {
opacity: 0.6;
}
li[data-task='/'] {
--#{$prefix}task-color: var(--#{$prefix}success);
}
li[data-task='!'] {
--#{$prefix}checkbox-color: var(--#{$prefix}danger);
}
li[data-task='?'] {
--#{$prefix}checkbox-color: var(--#{$prefix}warning);
}
dl {
dt {
font-weight: bold;
}
dd {
margin: 0.25em 0 1em;
}
}
ruby {
background: $code-background-color;
rt {
color: $global-font-secondary-color;
}
[data-theme='dark'] & {
background: $code-background-color-dark;
rt {
color: $global-font-secondary-color-dark;
}
}
}
mark {
padding: 0.14em 0.28em;
background-color: var(--#{$prefix}mark-background-color, mark);
color: var(--#{$prefix}mark-color, marktext);
@include border-radius($global-border-radius);
@each $color, $value in $theme-colors {
&.mark-#{$color} {
--#{$prefix}mark-color: #fff;
--#{$prefix}mark-background-color: var(--#{$prefix}#{$color});
}
}
}
.table-wrapper {
position: relative;
overflow-x: auto;
--#{$prefix}scrollbar-thumb-color: #{$table-background-color};
[data-theme='dark'] & {
--#{$prefix}scrollbar-thumb-color: #{$table-background-color-dark};
}
> table {
width: 100%;
max-width: 100%;
margin: 0.625rem 0;
border-spacing: 0;
background: $table-background-color;
border-collapse: collapse;
[data-theme='dark'] & {
background: $table-background-color-dark;
}
thead {
background: $table-thead-color;
[data-theme='dark'] & {
background-color: $table-thead-color-dark;
}
}
&:not([class]) tbody {
& tr:nth-child(odd) {
background: darken($table-background-color, 2.25%);
[data-theme='dark'] & {
background-color: lighten($table-background-color-dark, 2.75%);
}
}
& tr:hover {
background: darken($table-background-color, 4.5%);
[data-theme='dark'] & {
background-color: lighten($table-background-color-dark, 5.5%);
}
}
}
th,
td {
padding: 0.3rem 1rem;
border: 1px solid darken($table-thead-color, 2%);
[data-theme='dark'] & {
border-color: darken($table-thead-color-dark, 2%);
}
}
}
}
img {
max-width: 100%;
min-height: 1em;
&:not([height]) {
height: auto;
}
&[loading='lazy'][srcset]:not([data-lazyloaded]) {
&:not(.suffix-invalid__small) {
width: var(--width-small, var(--width));
aspect-ratio: var(--aspect-ratio-small, var(--aspect-ratio));
}
&:not(.suffix-invalid) {
@media (min-resolution: 1.01dppx) and (max-resolution: 1.5dppx) {
width: calc(var(--width) / 1.5);
aspect-ratio: var(--aspect-ratio);
}
}
&:not(.suffix-invalid__large) {
@media (min-resolution: 1.51dppx) {
width: calc(var(--width-large, var(--width)) / 2);
aspect-ratio: var(--aspect-ratio-large, var(--aspect-ratio));
}
}
}
&.version {
height: 1.25em;
vertical-align: text-bottom;
}
}
svg {
max-width: 100%;
}
figure {
margin: 0.5rem;
text-align: center;
.image-caption:not(:empty) {
min-width: 20%;
max-width: 80%;
display: inline-block;
padding: 0.5rem;
margin: 0 auto;
font-size: 0.875rem;
color: #969696;
}
img {
display: block;
margin: 0 auto;
overflow: hidden;
}
}
blockquote {
display: block;
border-left: 0.25em solid $global-border-color;
color: $blockquote-color;
padding: 0 1em;
margin: 1rem 0;
ul,
ol {
padding-left: 1.5em;
}
dl dd {
margin-inline-start: 0.25em;
}
[data-theme='dark'] & {
color: $blockquote-color-dark;
border-left-color: $global-border-color-dark;
}
@include link(false, true);
}
sup[id^='fnref']:has(.footnote-ref) {
padding: 2px 4px;
background-color: rgba(238, 238, 238, 0.7);
color: #555555;
border-radius: 4px;
cursor: pointer;
[data-theme='dark'] & {
background-color: rgba(56, 139, 253, 0.1);
color: #58a6ff;
}
@include link(true, false);
}
.footnotes {
font-size: 0.75rem;
white-space: normal;
color: darken($global-font-secondary-color, 5%);
ol {
margin-block: 1em;
padding-left: 1rem;
}
hr {
background-color: var(--#{$prefix}hr-background-color);
height: 1px;
margin-block: 1em;
}
code {
font-size: 0.75rem;
}
a:not(.footnote-backref) {
color: inherit;
text-decoration: underline;
}
@include link(false, true);
[data-theme='dark'] & {
color: lighten($global-font-secondary-color-dark, 5%);
}
p {
margin: 0.25rem 0;
}
}
kbd {
display: inline-block;
padding: 0 0.25rem;
background-color: $global-background-color;
border: 1px solid $global-border-color;
font-size: 0.8rem;
font-family: $code-font-family;
color: $code-color;
@include border-radius($global-border-radius);
@include box-shadow(inset 0 -1px 0 $global-border-color);
[data-theme='dark'] & {
background-color: $global-background-color-dark;
border: 1px solid $global-border-color-dark;
color: $code-color-dark;
@include box-shadow(inset 0 -1px 0 $global-border-color-dark);
}
}
// Katex styles
.katex-display {
max-width: 100%;
overflow-x: auto;
padding-block: 2px;
}
@import '../_partials/_single/alert';
@import '../_partials/_single/code';
@import '../_shortcodes';
}
@import '../_partials/_single/reward';
@import '../_partials/_single/footer';
@import '../_partials/_single/comment';
}
.lg-toolbar .lg-icon::after {
color: #999;
}
+63
View File
@@ -0,0 +1,63 @@
/**
* Style of layout named 'friends'.
* @Author: Lruihao <https://lruihao.cn>
* @Updated: 2022/3/11 21:36
*/
.friend-links {
margin-top: 1rem;
display: flex;
flex-direction: row;
justify-content: space-between;
flex-wrap: wrap;
}
@media (max-width: 576px) {
.friend-links {
justify-content: space-around;
}
}
.friend-link {
width: 150px;
height: 200px;
font-size: 1rem;
text-align: center;
background: rgba(255, 255, 255, 0.3);
box-sizing: border-box;
box-shadow: 3px 3px 5px #aaa;
@include border-radius($global-border-radius);
border: none;
transition-duration: 0.3s;
margin-bottom: 1rem;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.friend-link:hover {
background: #fff;
@include transform(scale(1.03));
box-shadow: 0 0 3px #aaa;
}
.friend-avatar {
object-fit: cover;
object-position: center;
width: 100% !important;
height: 150px !important;
@include border-radius($global-border-radius);
margin: 0;
padding: 0;
}
.friend-nickname {
display: block;
position: relative;
color: #2bbc8a;
font-weight: bold;
max-width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
line-height: 18px;
margin-bottom: 1rem;
}
.friend-nickname:hover {
color: #d480aa;
}
+14
View File
@@ -0,0 +1,14 @@
.special {
.single-title,
.single-subtitle {
text-align: right;
}
&.friends {
@import '_friends';
}
&.search {
@import '_search';
}
}
+10
View File
@@ -0,0 +1,10 @@
// Style of layout named 'search'
// TODO Adapting to dark mode, maybe use css variables
// Google CSE
.gcse-searchbox:empty,
.gcse-searchresults:empty {
display: none;
}
// Bing CSE (Unsupported)
+69
View File
@@ -0,0 +1,69 @@
.tag-cloud-tags {
margin: 10px 0;
@include link(true, true);
a {
display: inline-block;
position: relative;
margin: 5px 10px;
@include overflow-wrap(break-word);
@include transition(all ease-out 0.3s);
&:active,
&:focus,
&:hover {
@include transform(scale(1.2));
sup {
color: $global-font-color;
@include transition(all ease-out 0.3s);
[data-theme='dark'] & {
color: $global-font-color-dark;
}
}
}
sup {
color: $global-font-secondary-color;
[data-theme='dark'] & {
color: $global-font-secondary-color-dark;
}
}
}
}
@for $grade from 0 through 10 {
$tag-cloud-color: mix($tag-cloud-end, $tag-cloud-start, $grade * 10);
$tag-cloud-color-dark: mix($tag-cloud-end-dark, $tag-cloud-start-dark, $grade * 10);
.tag-cloud-#{$grade} {
color: $tag-cloud-color!important;
font-size: var(--tag-font);
margin: 10px!important;
&:active,
&:focus,
&:hover {
color: $global-link-hover-color!important;
[data-theme='dark'] & {
color: $global-link-hover-color-dark;
}
sup {
opacity: 1;
}
}
[data-theme='dark'] & {
color: $tag-cloud-color-dark!important;
}
sup {
opacity: 0;
}
}
}
@@ -1,7 +1,5 @@
@use "core/functions" as *;
@use "core/mixins" as *;
.taxonomy-cards {
.categories-card,
.collections-card {
margin: 0 auto;
display: flex;
align-items: flex-start;
@@ -12,7 +10,7 @@
.card-item {
font-size: 0.875rem;
text-align: start;
text-align: left;
width: 45%;
display: flex;
align-items: flex-start;
@@ -36,15 +34,11 @@
margin-bottom: 0.75rem;
}
.more-post {
text-align: end;
padding-inline-end: 1rem;
span {
float: right;
padding-right: 1rem;
}
}
@include media('xs') {
width: 100%;
}
}
}
@@ -53,8 +47,7 @@
justify-content: space-between;
align-items: center;
box-sizing: border-box;
margin-block: 0.25rem;
margin-inline: 1.5rem 0;
margin: 0.25rem 0 0.25rem 1.5rem;
}
.archive-item-link {
@@ -62,12 +55,32 @@
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
@include link(true, true);
&:hover {
color: $global-link-hover-color;
background-color: transparent;
}
[data-theme='dark'] & {
color: $global-link-color-dark;
&:hover {
color: $global-link-hover-color-dark;
}
}
}
.archive-item-date {
text-align: end;
color: fi-var(global-font-secondary-color);
text-align: right;
color: $global-font-secondary-color;
white-space: nowrap;
font-variant-numeric: tabular-nums lining-nums;
[data-theme='dark'] & {
color: $global-font-secondary-color-dark;
}
}
.more-post {
text-align: right;
}
+46
View File
@@ -0,0 +1,46 @@
.details {
> .details-summary {
@include border-radius($global-border-radius);
&:hover {
cursor: pointer;
}
i.details-icon {
color: $global-font-secondary-color;
@include transition(transform 0.2s ease);
[data-theme='dark'] & {
color: $global-font-secondary-color-dark;
}
}
}
> .details-content {
max-height: 0;
overflow-y: hidden;
@include details-transition-open;
}
&.open {
> .details-summary {
@include border-radius($global-border-radius $global-border-radius 0 0);
i.details-icon {
@include transform(rotate(90deg));
}
}
> .details-content {
max-height: 100%;
@include border-radius(0 0 $global-border-radius $global-border-radius);
@include details-transition-close;
}
}
&.disabled {
> .details-summary {
cursor: default;
}
}
}
+3
View File
@@ -0,0 +1,3 @@
img {
@include border-radius($global-border-radius/2);
}
@@ -1,5 +1,4 @@
/// Color map of admonitions.
/// @type Map
// Color map of admonitions
$admonition-color-map: (
note: (
color: #448aff,

Some files were not shown because too many files have changed in this diff Show More