Skip to content

trip2g/theme_editor_template

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

trip2g theme editor

A visual theme editor for trip2g's default template, shipped as a self-contained custom layout — the same mechanism the Kanban board rides on. No fork, no rebuild of trip2g.

The default template is styled entirely through Pico CSS v2.1.1 --pico-* custom properties. A theme is just a set of overrides for those variables. This editor makes that visual:

  • Live preview — an <iframe> of your real site (/) restyles in real time as you tweak sliders and color pickers.
  • Save — writes a <style>:root{…}</style> block into the admin Head HTML injection via the updateHtmlInjection GraphQL mutation, so the default template picks it up on every page. It upserts a single injection marked theme-editor instead of stacking duplicates. No JS is injected into your site — only CSS variables.

Install

The editor is one self-contained HTML file: _layouts/theme-editor.html (inline CSS/JS, no external dependencies, CSP-safe — the only network call is the same-origin GraphQL endpoint).

Drop it into your vault's _layouts/ folder as theme_editor.html:

curl -fsSL https://github.com/trip2g/theme_editor_template/releases/latest/download/theme_editor.html \
  -o _layouts/theme_editor.html

Then sync your vault (obsidian-sync, or however you publish).

Unlike the Kanban template, the editor does not load a JS bundle from a release — the whole app is inlined into the layout file, so the single HTML file is all you need.

Activate

Create a note with layout: theme_editor in its frontmatter (see example-vault/theme-editor.md):

---
layout: theme_editor
title: Theme editor
route: /theme-editor
free: true
noindex: true
---

Open that note while signed in as the site admin. The sign-in widget is in the top-right corner. Editing and preview work for anyone; Save requires admin (the server re-checks admin auth on the mutation).

Use

  • Type & shape tab — root variables that apply to both modes: fonts, base font size, line height, weight, corner radius, spacing, paragraph gap, and trip2g's --site-max-width.
  • Light / Dark tabs — per-mode colors (primary, background, text, cards, headings, code, highlight, borders …). Each is written under :root[data-theme="light"|"dark"] so light and dark theme independently.
  • A control with the ● marker is an active override; the × button clears it (falls back to the Pico default).
  • Reset clears every override; Save then persists the empty theme (removes it site-wide).
  • The Light/Dark switch above the preview flips which mode the iframe shows.
  • Preview target — the path box above the preview is editable: type any same-origin path (e.g. /en/user/themes, /ru/user/themes, a docs page) and press Enter to point the preview there. Docs / Home preset buttons are shortcuts. External URLs are rejected (only the path is kept, resolved against the site origin). The default is /en/user/themes — a plain default-template docs page — rather than the site home, which may carry its own custom styles.

Build

The layout is assembled from src/ by a zero-dependency Node script:

node build.mjs      # or: npm run build

It inlines src/editor.css and src/editor.js into src/theme-editor.template.html, writing dist/_layouts/theme-editor.html.

src/
  theme-editor.template.html   Jet layout wrapper (head chrome + data markers)
  editor.css                   editor styles
  editor.js                    editor logic (plain JS, no framework)
build.mjs                      inliner → dist/_layouts/theme-editor.html
dist/_layouts/theme-editor.html  built artifact (the thing you install)
example-vault/                 sample note + layout for local testing

How it works (the contract)

  • Endpoint: POST /_system/graphql, credentials: 'include' (session cookie). Same path and auth the $mol user-space bundle uses.
  • Load: query { admin { allHtmlInjections { nodes { id description placement content position } } } }, then pick the node whose description == "theme-editor".
  • Save (upsert):
    • new → createHtmlInjection(input: { description: "theme-editor", position: 0, placement: "head", content })
    • existing → updateHtmlInjection(input: { id, description: "theme-editor", position: 0, placement: "head", content })
    • content is the generated <style>…</style> block. placement must be "head" (validated server-side as one of head | body_end); Head renders after the base stylesheet, so overrides win.
  • Auth: admin. Mutations run under admin { … } and the resolver calls CurrentAdminUserToken; a non-admin session gets unauthorized.

Testing

Static verification (no instance needed):

node build.mjs           # builds the layout
node --check src/editor.js

Live round-trip (needs a trip2g instance where you have admin):

  1. Copy dist/_layouts/theme-editor.html into the instance vault's _layouts/.
  2. Add a note with layout: theme_editor and sync.
  3. Open the note as admin, tweak a variable, watch the iframe restyle, click Save.
  4. Reload any other page — the theme applies site-wide.
  5. Check Admin → SEO & URLs → HTML Injections: there is exactly one injection named theme-editor; saving again updates it in place (no duplicates).

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages