Compare commits

...

39 Commits

Author SHA1 Message Date
6d99376c03 Update tagline
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 11s
2025-05-05 17:28:12 -04:00
b17a2a381e Update blog
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 10s
2025-05-05 17:24:43 -04:00
38191d9b01 tweak post
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 13s
2025-05-04 20:52:44 -04:00
4752b37cd0 Add Exploring Falyx
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 11s
2025-05-04 20:47:59 -04:00
f6214c2e65 Update DOCKERFILE
Some checks failed
rtj.dev Build and Deploy / Build-and-Deploy (push) Failing after 6s
2025-04-15 23:50:18 -04:00
10773e44d3 Update DOCKERFILE
Some checks failed
rtj.dev Build and Deploy / Build-and-Deploy (push) Failing after 11s
2025-04-15 23:47:48 -04:00
796773017b Update DOCKERFILE
Some checks failed
rtj.dev Build and Deploy / Build-and-Deploy (push) Failing after 7s
2025-04-15 23:43:22 -04:00
bd92fa55e7 Update hugo.toml
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 7s
2025-04-15 23:39:50 -04:00
6703c5299b Update HUGO
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 8s
2025-04-15 23:10:15 -04:00
8fcd5de6a6 Add Falyx
Some checks failed
rtj.dev Build and Deploy / Build-and-Deploy (push) Failing after 7s
2025-04-15 23:00:50 -04:00
f1a86068dc Fix header.html partial, update pagination in hugo.toml
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 11s
2025-02-01 19:00:37 -05:00
fa1c0d6602 Update PaperMod
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 26s
2025-02-01 18:36:22 -05:00
db4de72d94 -!
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 10s
2024-02-18 01:53:58 -05:00
2e2cc658cf Revert
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 7s
2024-02-16 18:54:16 -05:00
f4e91dff49 Use docker-login action
Some checks failed
rtj.dev Build and Deploy / Build-and-Deploy (push) Failing after 6s
2024-02-16 17:53:09 -05:00
b25856ab60 !
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 9s
2024-02-15 19:26:01 -05:00
452a6d3b6d -!
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 8s
2024-02-15 19:07:23 -05:00
5d3ad656f3 !
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 8s
2024-02-15 18:56:11 -05:00
4d8ea8436b Revert
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 8s
2024-02-14 23:02:47 -05:00
b3c8aaf561 !
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 7s
2024-02-13 13:39:35 -05:00
2896518816 Update workflow
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 7s
2024-02-12 23:35:51 -05:00
2d9c6233ad Update workflow
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 7s
2024-02-12 23:35:01 -05:00
3aede7ab00 Update workflow
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 8s
2024-02-12 23:28:13 -05:00
4b2bc03b15 Revert and Test deploy
Some checks failed
rtj.dev Build and Deploy / Build-and-Deploy (push) Failing after 8s
2024-02-12 23:00:29 -05:00
9a33c9cb62 Testing deploy
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 10s
2024-02-12 22:56:00 -05:00
68cdf40a61 Add example post
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 9s
2024-02-12 22:53:06 -05:00
11195e2836 Add curl
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 8s
2024-02-12 22:45:48 -05:00
ee86d69746 Change base docker image
Some checks failed
rtj.dev Build and Deploy / Build-and-Deploy (push) Failing after 24s
2024-02-12 22:44:15 -05:00
f3ae24ac9f Test workflow
Some checks failed
rtj.dev Build and Deploy / Build-and-Deploy (push) Failing after 7s
2024-02-12 22:36:14 -05:00
46a4e21a8b Update PaperMod, svg.html
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 9s
2023-11-06 11:17:11 -05:00
dd2b59e689 Update PaperMod, svg.html
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 9s
2023-09-30 12:32:46 -04:00
ffbdd9ae86 Add linkedin
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 17s
2023-08-18 21:09:33 -04:00
26f001b0c2 Update styling
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 9s
2023-08-03 23:53:49 -04:00
83cba148b4 Adjust logo size
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 9s
2023-08-03 18:45:58 -04:00
a78312583e Adjust logo size
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 8s
2023-08-03 11:26:07 -04:00
ab47db789d Add gitea_rtj_logo
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 8s
2023-08-03 09:57:54 -04:00
88a21cd8b4 Add custom css
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 7s
2023-07-31 08:41:53 -04:00
e4fd42b7aa Move favicons
All checks were successful
rtj.dev Build and Deploy / Build-and-Deploy (push) Successful in 10s
2023-07-30 23:26:50 -04:00
db107236f6 Move favicons 2023-07-30 23:25:44 -04:00
18 changed files with 884 additions and 26 deletions

View File

@ -11,14 +11,11 @@ jobs:
steps:
- name: Setup node.js
run: |
apk --update add nodejs npm git
apk --update add nodejs npm git curl
- name: Check out repository code recursively
uses: actions/checkout@v3
with:
submodules: recursive
- name: Print repository name
run: |
echo "💡 The "${{ gitea.repository }}" repository has been cloned to the runner."
- name: Pass login information
run: |
mkdir -p $HOME/.docker
@ -28,3 +25,6 @@ jobs:
cd ${{ gitea.workspace }}
docker build -f Dockerfile -t git.rtj.dev/roland/rtj.dev:0.0.1 .
docker push git.rtj.dev/roland/rtj.dev:0.0.1
- name: Signal Restart
run: |
curl ${{ secrets.OPTIONS }} "${{ secrets.API_KEY }}" ${{ secrets.ENDPOINT }}

View File

@ -1,5 +1,5 @@
FROM klakegg/hugo:ext-alpine-onbuild as hugo
FROM floryn90/hugo:0.146.5-alpine-onbuild as hugo
USER root
FROM nginx
COPY --from=hugo /target /usr/share/nginx/html
COPY default.conf /etc/nginx/conf.d/

View File

@ -0,0 +1,10 @@
.dark {
--theme: #070707;
--entry: #1A1A1F;
--code-bg: #1A1A1F;
--hljs-bg: #1A1A1F;
}
.dark.list {
background: #070707;
}

View File

@ -0,0 +1,309 @@
/*
* Copyright (c) 2017-present Arctic Ice Studio <development@arcticicestudio.com>
* Copyright (c) 2017-present Sven Greb <development@svengreb.de>
*
* Project: Nord highlight.js
* Version: 0.1.0
* Repository: https://github.com/arcticicestudio/nord-highlightjs
* License: MIT
* References:
* https://github.com/arcticicestudio/nord
*/
.hljs {
display: block;
overflow-x: auto;
padding: 0.5em;
background: #2E3440;
}
.hljs,
.hljs-subst {
color: #D8DEE9;
}
.hljs-selector-tag {
color: #81A1C1;
}
.hljs-selector-id {
color: #8FBCBB;
font-weight: bold;
}
.hljs-selector-class {
color: #8FBCBB;
}
.hljs-selector-attr {
color: #8FBCBB;
}
.hljs-selector-pseudo {
color: #88C0D0;
}
.hljs-addition {
background-color: rgba(163, 190, 140, 0.5);
}
.hljs-deletion {
background-color: rgba(191, 97, 106, 0.5);
}
.hljs-built_in,
.hljs-type {
color: #8FBCBB;
}
.hljs-class {
color: #8FBCBB;
}
.hljs-function {
color: #88C0D0;
}
.hljs-function > .hljs-title {
color: #88C0D0;
}
.hljs-keyword,
.hljs-literal,
.hljs-symbol {
color: #81A1C1;
}
.hljs-number {
color: #B48EAD;
}
.hljs-regexp {
color: #EBCB8B;
}
.hljs-string {
color: #A3BE8C;
}
.hljs-title {
color: #8FBCBB;
}
.hljs-params {
color: #D8DEE9;
}
.hljs-bullet {
color: #81A1C1;
}
.hljs-code {
color: #8FBCBB;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-formula {
color: #8FBCBB;
}
.hljs-strong {
font-weight: bold;
}
.hljs-link:hover {
text-decoration: underline;
}
.hljs-quote {
color: #4C566A;
}
.hljs-comment {
color: #4C566A;
}
.hljs-doctag {
color: #8FBCBB;
}
.hljs-meta,
.hljs-meta-keyword {
color: #5E81AC;
}
.hljs-meta-string {
color: #A3BE8C;
}
.hljs-attr {
color: #8FBCBB;
}
.hljs-attribute {
color: #D8DEE9;
}
.hljs-builtin-name {
color: #81A1C1;
}
.hljs-name {
color: #81A1C1;
}
.hljs-section {
color: #88C0D0;
}
.hljs-tag {
color: #81A1C1;
}
.hljs-variable {
color: #D8DEE9;
}
.hljs-template-variable {
color: #D8DEE9;
}
.hljs-template-tag {
color: #5E81AC;
}
.abnf .hljs-attribute {
color: #88C0D0;
}
.abnf .hljs-symbol {
color: #EBCB8B;
}
.apache .hljs-attribute {
color: #88C0D0;
}
.apache .hljs-section {
color: #81A1C1;
}
.arduino .hljs-built_in {
color: #88C0D0;
}
.aspectj .hljs-meta {
color: #D08770;
}
.aspectj > .hljs-title {
color: #88C0D0;
}
.bnf .hljs-attribute {
color: #8FBCBB;
}
.clojure .hljs-name {
color: #88C0D0;
}
.clojure .hljs-symbol {
color: #EBCB8B;
}
.coq .hljs-built_in {
color: #88C0D0;
}
.cpp .hljs-meta-string {
color: #8FBCBB;
}
.css .hljs-built_in {
color: #88C0D0;
}
.css .hljs-keyword {
color: #D08770;
}
.diff .hljs-meta {
color: #8FBCBB;
}
.ebnf .hljs-attribute {
color: #8FBCBB;
}
.glsl .hljs-built_in {
color: #88C0D0;
}
.groovy .hljs-meta:not(:first-child) {
color: #D08770;
}
.haxe .hljs-meta {
color: #D08770;
}
.java .hljs-meta {
color: #D08770;
}
.ldif .hljs-attribute {
color: #8FBCBB;
}
.lisp .hljs-name {
color: #88C0D0;
}
.lua .hljs-built_in {
color: #88C0D0;
}
.moonscript .hljs-built_in {
color: #88C0D0;
}
.nginx .hljs-attribute {
color: #88C0D0;
}
.nginx .hljs-section {
color: #5E81AC;
}
.pf .hljs-built_in {
color: #88C0D0;
}
.processing .hljs-built_in {
color: #88C0D0;
}
.scss .hljs-keyword {
color: #81A1C1;
}
.stylus .hljs-keyword {
color: #81A1C1;
}
.swift .hljs-meta {
color: #D08770;
}
.vim .hljs-built_in {
color: #88C0D0;
font-style: italic;
}
.yaml .hljs-meta {
color: #D08770;
}

View File

@ -0,0 +1,196 @@
---
author: "Roland Thomas Jr"
title: "Exploring Falyx"
date: "2025-05-04"
description: ""
tags: ["post", "falyx", "cli"]
ShowToc: false
ShowBreadCrumbs: true
---
## 🛠️ Exploring Falyx: Three Powerful Ways to Build Python CLIs
Falyx is a modern Python CLI framework for building structured, resilient workflows — whether you're scaffolding a new CLI, automating tasks, or managing global developer utilities.
In this post, we'll explore the three main modes of using Falyx:
1. **Interactive Menu Mode**
2. **CLI Execution Mode**
3. **Python API Mode**
---
### 1. 🧭 Interactive Menu Mode
In this mode, Falyx provides an interactive menu-driven interface, allowing users to navigate and execute tasks seamlessly.
#### How It Works
By defining your CLI structure in a configuration file (`falyx.yaml` or `falyx.toml`), Falyx can automatically generate an interactive menu. This menu leverages `prompt_toolkit` and `rich` to offer a user-friendly interface.
#### Example
```bash
$ falyx
🛠️ Config-Driven CLI
[C] Cleanup temp files
[Y] History [H] Help [Q] Exit
>
```
This command launches the interactive menu, displaying available tasks and options.
#### Ideal For
- Project scaffolding and task runners
- Internal tools with multiple operations
- Users who prefer guided, menu-based interactions
---
### 2. ⚙️ CLI Execution Mode
For users who prefer direct command execution, Falyx offers a CLI mode that allows tasks to be run via specific keys or aliases.
#### How It Works
Each task defined in your configuration file is assigned a unique key or alias. You can execute these tasks directly from the command line.
#### Example
```bash
$ falyx run R
```
This command executes the task associated with the key `R`.
#### Ideal For
- Scripting and automation
- CI/CD pipelines
- Users who prefer quick, direct command execution
---
### 3. 🐍 Python API Mode
Falyx isn't just a CLI tool; it's also a Python framework that can be integrated directly into your applications.
#### How It Works
By importing Falyx into your Python code, you can programmatically define and execute tasks, offering greater flexibility and integration capabilities.
#### Example
```python
import asyncio
from falyx import Falyx, Action
async def my_task():
print("Executing my task")
falyx = Falyx(title="My CLI")
falyx.add_command(
key="M",
description="Run my task",
action=Action(name="my_task", action=my_task)
)
asyncio.run(falyx.run())
```
#### Ideal For
- Embedding CLI capabilities into Python applications
- Dynamic task generation
- Advanced integrations and custom workflows
---
### 🚀 Getting Started
To begin using Falyx, install it via pip:
```bash
pip install falyx
```
Then, initialize your project:
```bash
falyx init project_name
```
This command scaffolds an example project in the specified directory.
#### Common Commands
- `falyx init my-cli` to scaffold a new CLI
- `falyx run key` to run a task
- `falyx` to launch the interactive menu
- `falyx init-global` to define reusable global tasks
---
Falyx's multi-modal approach ensures that it can adapt to various workflows and user preferences. Whether you're building interactive menus, automating tasks via the CLI, or integrating with Python applications, Falyx provides the tools and flexibility to enhance your development experience.
Feel free to explore more on [Falyx's GitHub repository](https://github.com/rolandtjr/falyx) and contribute to its development!
Ready to build your next terminal workflow? Try falyx init or falyx init-global and see what Falyx can do for you.
---
### 🌍 Bonus: Global Task Runner with `falyx init-global`
Falyx also supports defining reusable, system-wide tasks via a global configuration file. You can set this up with:
```bash
falyx init-global
```
This creates the directory:
```
~/.config/falyx/
```
And adds a starter `falyx.yaml` and `tasks.py`, for example:
**\~/.config/falyx/falyx.yaml**
```yaml
- key: D
description: Update dotfiles
action: dotfiles.update
aliases: [update-dotfiles]
```
**\~/.config/falyx/dotfiles.py**
```python
async def update():
print("Updating dotfiles...")
```
Once initialized, you can run tasks from anywhere:
```bash
falyx run D
falyx run update-dotfiles
falyx # view all global tasks as a menu
```
Falyx will automatically detect and use this config when no project config is present, and temporarily add its location to `PYTHONPATH` so imports like `dotfiles.update` just work.
#### Ideal For
* Personal automation (e.g., dotfiles, system restarts, daily routines)
* Lightweight global dev tools
* One-liner task execution from anywhere
---

114
content/posts/falyx.md Normal file
View File

@ -0,0 +1,114 @@
---
author: "Roland Thomas Jr"
title: "Falyx"
date: "2025-04-15"
description: ""
tags: ["post", "falyx", "cli"]
ShowToc: false
ShowBreadCrumbs: true
---
## 🛡️ Introducing Falyx: A Resilient CLI Framework for Modern Workflows
In the ever-evolving landscape of software development, tools that offer resilience, clarity, and introspection are invaluable.
Enter **Falyx**—a robust, asynchronous command-line interface (CLI) framework designed to streamline and fortify your workflows.
### ⚙️ What is Falyx?
Falyx is a Python-based CLI framework that empowers developers to build **modular**, **fault-tolerant** command-line applications. Inspired by the discipline and strength of a phalanx, Falyx ensures that each component of your workflow stands firm — even in the face of failure.
### 🚀 Key Features
- **Modular Action Chaining** Compose complex workflows by chaining together discrete actions, each with its own context and lifecycle.
- **Built-in Retry Mechanism** Handle flaky or transient failures with configurable retry policies, including exponential backoff.
- **Lifecycle Hooks** Inject logic at every stage: `before`, `after`, `on_success`, `on_error`, and `on_teardown`.
- **Execution Tracing** Built-in logging, result tracking, and timing for complete visibility.
- **Async-First Design** Built on `asyncio`, with optional multiprocessing via `ProcessAction`.
- **Extensible CLI Menus** Create interactive or headless menus using `prompt_toolkit` and `rich`, with support for history, tags, toggle states, and more.
### 🧪 Getting Started
Here's a simple example to illustrate how Falyx can be used to build a resilient CLI application:
```python
import asyncio
import random
from falyx import Falyx, Action, ChainedAction
# Define a flaky asynchronous step
async def flaky_step():
await asyncio.sleep(0.2)
if random.random() < 0.5:
raise RuntimeError("Random failure!")
return "ok"
# Create actions with retry enabled
step1 = Action(name="step_1", action=flaky_step, retry=True)
step2 = Action(name="step_2", action=flaky_step, retry=True)
# Chain the actions together
chain = ChainedAction(name="my_pipeline", actions=[step1, step2])
# Set up the CLI menu
falyx = Falyx("🚀 Falyx Demo")
falyx.add_command(
key="R",
description="Run My Pipeline",
action=chain,
logging_hooks=True,
preview_before_confirm=True,
confirm=True,
)
# Entry point
if __name__ == "__main__":
asyncio.run(falyx.run())
```
When run, this script presents an interactive CLI menu with built-in preview, confirmation, and retry handling.
```bash
python simple.py
🚀 Falyx Demo
[R] Run My Pipeline
[Y] History [Q] Exit
>
```
Or run headlessly using intuitive CLI arguments:
```bash
python simple.py run R
Command: 'R' — Run My Pipeline
└── ⛓ ChainedAction 'my_pipeline'
├── ⚙ Action 'step_1'
│ ↻ Retries: 3x, delay 1.0s, backoff 2.0x
└── ⚙ Action 'step_2'
↻ Retries: 3x, delay 1.0s, backoff 2.0x
Confirm execution of R — Run My Pipeline (calls `my_pipeline`) [Y/n] y
[2025-04-15 22:03:57] WARNING ⚠️ Retry attempt 1/3 failed due to 'Random failure!'.
✅ Result: ['ok', 'ok']
```
### 📈 Real-World Applications
Falyx is particularly well-suited for:
- **Automation Script**: Build resilient tools that self-heal from transient errors.
- **Data Pipelines**: Orchestrate complex data flows with retry logic and full observability.
- **Deployment Tooling**: Create safe deploys with preview, rollback, and confirmation baked in.
### 📚 Learn More
- 📖 [Source Code on GitHub](https://github.com/rolandtjr/falyx)
---
Falyx was designed for developers who dont just want CLI tools to **run** — they want them to **recover**, **report**, and **adapt**.
If that sounds like you, give it a spin and start building resilient command flows today.
> _"Like a phalanx: organized, resilient, and reliable."_ ⚔️
---

View File

@ -1,15 +1,16 @@
baseURL = 'https://rtj.dev/'
languageCode = 'en-us'
title = 'rtj.dev'
paginate = 10
pagination.pagerSize = 10
theme = 'PaperMod'
enableEmoji = true
pygmentsUseClasses = true
googleAnalytics = 'G-9BHN5G7N67'
[params]
env = 'production'
author = 'Roland Thomas Jr'
defaultTheme = 'auto'
defaultTheme = 'dark'
disableThemeToggle = false
ShowShareButtons = true
ShowCodeCopyButtons = true
ShowPostNavLinks = true
@ -19,26 +20,36 @@ ShowReadingTime = true
ShowToc = false
[params.label]
icon = "/favicons/apple-touch-icon.png"
text = ".dev"
icon = "/apple-touch-icon.png"
text = " "
iconHeight = 40
[params.gitea]
icon = "/gitea_rtj_logo.png"
text = "git.rtj.dev"
site = "https://git.rtj.dev"
iconHeight = 30
[params.assets]
favicon = "/favicons/favicon.ico"
favicon16x16 = "/favicons/favicon-16x16.png"
favicon32x32 = "/favicons/favicon-32x32.png"
apple_touch_icon = "/favicons/apple-touch-icon.png"
android_chrome_192x192 = "/favicons/android-chrome-192x192"
android_chrome_512x512 = "/favicons/android-chrome-512x512"
favicon = "/favicon.ico"
favicon16x16 = "/favicon-16x16.png"
favicon32x32 = "/favicon-32x32.png"
apple_touch_icon = "/apple-touch-icon.png"
android_chrome_192x192 = "/android-chrome-192x192"
android_chrome_512x512 = "/android-chrome-512x512"
[params.homeInfoParams]
Title = "Roland Thomas Jr \U0001F525"
Content = 'Welcome to my blog!'
Content = "I'm a systems-minded engineer with a focus on resilient tooling, DevSecOps automation, and CLI architecture.\n\nI build frameworks like [Falyx](https://github.com/rolandtjr/falyx) to turn complex workflows into reliable command-line experiences — in YAML or code.\n\n > “Automation should be composable, introspectable, and a pleasure to maintain.“"
[[params.socialIcons]]
name = 'github'
url = 'https://github.com/rolandtjr'
[[params.socialIcons]]
name = 'linkedin'
url = 'https://www.linkedin.com/in/roland-thomas-jr'
[[params.socialIcons]]
name = 'codewars'
url = 'https://www.codewars.com/users/rolandtjr'
@ -63,8 +74,10 @@ ShowToc = false
name = 'Rss'
url = 'index.xml'
[languages]
[languages.en]
languageName = 'English'
languageCode = 'en-us'
weight = 1
[languages.en.taxonomies]
@ -87,10 +100,5 @@ name = "Tags"
url = "tags/"
weight = 10
[[languages.en.menu.main]]
name = "git.rtj.dev"
url = "https://git.rtj.dev"
weight = 15
[outputs]
home = [ "HTML", "RSS", "JSON" ]

View File

@ -0,0 +1,181 @@
{{- /* theme-toggle is enabled */}}
{{- if (not site.Params.disableThemeToggle) }}
{{- /* theme is light */}}
{{- if (eq site.Params.defaultTheme "light") }}
<script>
if (localStorage.getItem("pref-theme") === "dark") {
document.body.classList.add('dark');
}
</script>
{{- /* theme is dark */}}
{{- else if (eq site.Params.defaultTheme "dark") }}
<script>
if (localStorage.getItem("pref-theme") === "light") {
document.body.classList.remove('dark')
}
</script>
{{- else }}
{{- /* theme is auto */}}
<script>
if (localStorage.getItem("pref-theme") === "dark") {
document.body.classList.add('dark');
} else if (localStorage.getItem("pref-theme") === "light") {
document.body.classList.remove('dark')
} else if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.body.classList.add('dark');
}
</script>
{{- end }}
{{- /* theme-toggle is disabled and theme is auto */}}
{{- else if (and (ne site.Params.defaultTheme "light") (ne site.Params.defaultTheme "dark"))}}
<script>
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.body.classList.add('dark');
}
</script>
{{- end }}
<header class="header">
<nav class="nav">
<div class="logo">
{{- $label_text := (site.Params.label.text | default site.Title) }}
{{- if site.Title }}
<a href="{{ "" | absLangURL }}" accesskey="h" title="{{ site.Title }} (Alt + H)">
{{- if site.Params.label.icon }}
{{- $img := resources.Get site.Params.label.icon }}
{{- if $img }}
{{- $processableFormats := (slice "jpg" "jpeg" "png" "tif" "bmp" "gif") -}}
{{- if hugo.IsExtended -}}
{{- $processableFormats = $processableFormats | append "webp" -}}
{{- end -}}
{{- $prod := (hugo.IsProduction | or (eq site.Params.env "production")) }}
{{- if and (in $processableFormats $img.MediaType.SubType) (eq $prod true)}}
{{- if site.Params.label.iconHeight }}
{{- $img = $img.Resize (printf "x%d" site.Params.label.iconHeight) }}
{{ else }}
{{- $img = $img.Resize "x30" }}
{{- end }}
{{- end }}
<img src="{{ $img.Permalink }}" alt="" aria-label="logo"
height="{{- site.Params.label.iconHeight | default "30" -}}">
{{- else }}
<img src="{{- site.Params.label.icon | absURL -}}" alt="" aria-label="logo"
height="{{- site.Params.label.iconHeight | default "30" -}}">
{{- end -}}
{{- else if hasPrefix site.Params.label.iconSVG "<svg" }}
{{ site.Params.label.iconSVG | safeHTML }}
{{- end -}}
{{- $label_text -}}
</a>
{{- end }}
<div class="logo-switches">
{{- if (not site.Params.disableThemeToggle) }}
<button id="theme-toggle" accesskey="t" title="(Alt + T)">
<svg id="moon" xmlns="http://www.w3.org/2000/svg" width="24" height="18" viewBox="0 0 24 24"
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round">
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
</svg>
<svg id="sun" xmlns="http://www.w3.org/2000/svg" width="24" height="18" viewBox="0 0 24 24"
fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round"
stroke-linejoin="round">
<circle cx="12" cy="12" r="5"></circle>
<line x1="12" y1="1" x2="12" y2="3"></line>
<line x1="12" y1="21" x2="12" y2="23"></line>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
<line x1="1" y1="12" x2="3" y2="12"></line>
<line x1="21" y1="12" x2="23" y2="12"></line>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
</svg>
</button>
{{- end }}
{{- $lang := .Lang}}
{{- $separator := or $label_text (not site.Params.disableThemeToggle)}}
{{- with site.Home.Translations }}
<ul class="lang-switch">
{{- if $separator }}<li>|</li>{{ end }}
{{- range . -}}
{{- if ne $lang .Lang }}
<li>
<a href="{{- .Permalink -}}" title="{{ .Language.Params.languageAltTitle | default (.Language.LanguageName | emojify) | default (.Lang | title) }}"
aria-label="{{ .Language.LanguageName | default (.Lang | title) }}">
{{- if (and site.Params.displayFullLangName (.Language.LanguageName)) }}
{{- .Language.LanguageName | emojify -}}
{{- else }}
{{- .Lang | title -}}
{{- end -}}
</a>
</li>
{{- end -}}
{{- end}}
</ul>
{{- end }}
</div>
</div>
{{- $currentPage := . }}
<ul id="menu">
{{- range site.Menus.main }}
{{- $menu_item_url := (cond (strings.HasSuffix .URL "/") .URL (printf "%s/" .URL) ) | absLangURL }}
{{- $page_url:= $currentPage.Permalink | absLangURL }}
{{- $is_search := eq (site.GetPage .KeyName).Layout `search` }}
<li>
<a href="{{ .URL | absLangURL }}" title="{{ .Title | default .Name }} {{- cond $is_search (" (Alt + /)" | safeHTMLAttr) ("" | safeHTMLAttr ) }}"
{{- cond $is_search (" accesskey=/" | safeHTMLAttr) ("" | safeHTMLAttr ) }}>
<span {{- if eq $menu_item_url $page_url }} class="active" {{- end }}>
{{- .Pre }}
{{- .Name -}}
{{ .Post -}}
</span>
{{- if (findRE "://" .URL) }}&nbsp;
<svg fill="none" shape-rendering="geometricPrecision" stroke="currentColor" stroke-linecap="round"
stroke-linejoin="round" stroke-width="2.5" viewBox="0 0 24 24" height="12" width="12">
<path d="M18 13v6a2 2 0 01-2 2H5a2 2 0 01-2-2V8a2 2 0 012-2h6"></path>
<path d="M15 3h6v6"></path>
<path d="M10 14L21 3"></path>
</svg>
{{- end }}
</a>
</li>
{{- end }}
<div class="logo">
<li>
{{- if site.Params.gitea.text }}
<a href="{{ site.Params.gitea.site }}" accesskey="g" title="{{ site.Params.gitea.text }} (Alt + G)">
{{- if site.Params.gitea.icon }}
{{- $img := resources.Get site.Params.gitea.icon }}
{{- if $img }}
{{- $processableFormats := (slice "jpg" "jpeg" "png" "tif" "bmp" "gif") -}}
{{- if hugo.IsExtended -}}
{{- $processableFormats = $processableFormats | append "webp" -}}
{{- end -}}
{{- $prod := (hugo.IsProduction | or (eq site.Params.env "production")) }}
{{- if and (in $processableFormats $img.MediaType.SubType) (eq $prod true)}}
{{- if site.Params.gitea.iconHeight }}
{{- $img = $img.Resize (printf "x%d" site.Params.gitea.iconHeight) }}
{{ else }}
{{- $img = $img.Resize "x30" }}
{{- end }}
{{- end }}
<img src="{{ $img.Permalink }}" alt="" aria-label="logo"
height="{{- site.Params.gitea.iconHeight | default "30" -}}">
{{- else }}
<img src="{{- site.Params.gitea.icon | absURL -}}" alt="" aria-label="logo"
height="{{- site.Params.gitea.iconHeight | default "30" -}}">
{{- end -}}
{{- else if hasPrefix site.Params.gitea.iconSVG "<svg" }}
{{ site.Params.gitea.iconSVG | safeHTML }}
{{- end -}}
{{- end }}
</a>
</li>
</div>
</ul>
</nav>
</header>

File diff suppressed because one or more lines are too long

View File

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

View File

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 16 KiB

View File

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

View File

Before

Width:  |  Height:  |  Size: 552 B

After

Width:  |  Height:  |  Size: 552 B

View File

Before

Width:  |  Height:  |  Size: 920 B

After

Width:  |  Height:  |  Size: 920 B

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

BIN
static/gitea_rtj_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 MiB