# Website Architecture: Aki JSON Pattern This website follows the **Aki architecture** (inspired by [Aki](https://github.com/vilgacx/aki)), which uses a "JSON-as-data" approach to create a fast, Single-Page Application (SPA) experience without a heavy framework. ## Core Principle Instead of full page reloads, the frontend fetches JSON objects from the server. These objects contain the HTML content, which is then dynamically injected into the DOM using simple JavaScript selectors. ## System Flow 1. **Markdown Source**: Content is authored in `content/` as Markdown files. 2. **Build Step**: Running `./rebuild.sh` (which triggers `generate_json.php`) converts Markdown into HTML. 3. **JSON Generation**: The HTML is wrapped in a JSON structure and saved to the `public/` directory: ```json { "section": { "innerHTML": "

Page Title

Content...

" } } ``` 4. **Frontend Loading**: * The user clicks a link with the attributes `fn="onclick"` and `url="public/page/index.json"`. * JavaScript intercepts the click, fetches the JSON, and iterates through the keys. * For each key (e.g., `section`), it finds the corresponding DOM element (`document.querySelector('section')`) and updates its property (e.g., `innerHTML`). ## Key Components - **`index.php`**: The main shell. It contains the base HTML structure and the JavaScript logic for the Aki JSON loader. - **`generate_json.php`**: The engine that converts Markdown to Aki-compatible JSON. It handles path-fixing to ensure images and links work correctly in the `envs.net` subdirectory (`/~username/`). - **`rebuild.sh`**: A convenience shell script to trigger the regeneration of the `public/` JSON files. - **`lib/ContentRenderer.php`**: Uses `comrak` to render high-quality Github Flavored Markdown. - **`lib/ContentManager.php`**: Handles discovery of content sections and blog posts. ## Comparison with Full JavaScript Frameworks (e.g., React, Vue, Angular) The Aki JSON pattern offers a simpler, more direct approach to building single-page applications compared to comprehensive JavaScript frameworks. The key differences lie in complexity, performance characteristics, and development paradigm. ### 1. Bundle Size and Initial Load - **Aki Pattern**: Very small initial JavaScript payload. The `index.php` loads quickly with minimal JS, and subsequent content is fetched as HTML snippets within JSON. This results in a fast Time-To-Interactive (TTI) as the browser can render HTML progressively. - **Full JS Frameworks**: Typically involve larger JavaScript bundles that need to be downloaded and parsed before the application can become interactive (though techniques like code-splitting and server-side rendering/hydration mitigate this). This can lead to slower initial page loads, especially on less powerful devices or poor network connections. ### 2. Development Complexity and Tooling - **Aki Pattern**: - **Simplicity**: Leverages native browser capabilities (Fetch API, DOM manipulation). - **Minimal Tooling**: Primarily relies on PHP for content generation and basic shell scripts. No complex build pipelines (Webpack, Vite), state management libraries (Redux, Vuex), or component-based architectures. - **HTML-centric**: Developers largely work with Markdown and basic PHP templates, focusing on content structure and presentation. - **Full JS Frameworks**: - **Comprehensive Ecosystem**: Offers rich component models, sophisticated state management, routing libraries, and powerful development tools. - **Steeper Learning Curve**: Requires understanding of modern JavaScript (ES6+), JSX/templating syntaxes, build processes, and framework-specific patterns. - **Complex Tooling**: Often necessitates a build step with bundlers, transpilers, and other development dependencies. ### 3. SEO and Accessibility - **Aki Pattern**: - **Client-Side Rendering (CSR) with HTML in JSON**: The initial `index.php` provides a basic HTML shell. Content is dynamically injected into the `#panel` via JavaScript. This means search engine crawlers that do not execute JavaScript might not see the full content immediately. However, many modern crawlers (like Google's) are capable of rendering JavaScript. - **Accessible HTML Snippets**: Once content is loaded, it's standard HTML, which is generally accessible. - **Full JS Frameworks**: - **Default CSR Issues**: By default, many frameworks also render client-side, posing similar SEO challenges. - **SSR/SSG/Hydration**: Modern frameworks often address SEO and TTI by integrating Server-Side Rendering (SSR) or Static Site Generation (SSG) with client-side "hydration," which adds significant architectural complexity. ### 4. Interactivity and Dynamic Features - **Aki Pattern**: - **Limited Dynamic Functionality**: Primarily focuses on content delivery and simple navigation. Complex, highly interactive UI components (e.g., real-time forms, drag-and-drop interfaces) would require custom JavaScript for each feature. - **Direct DOM Manipulation**: Relies on direct `innerHTML` assignments, which can sometimes be less performant or harder to manage for very complex updates compared to virtual DOM approaches. - **Full JS Frameworks**: - **Rich Interactivity**: Excel at building highly dynamic and complex user interfaces with reactive data binding and efficient DOM updates (via Virtual DOM). - **Component Reusability**: Encourages building reusable UI components, speeding up development for feature-rich applications. ### 5. Use Cases and Philosophy - **Aki Pattern**: Ideal for content-heavy sites (blogs, documentation, simple portfolios) where the primary goal is fast content delivery and navigation with minimal overhead. It prioritizes simplicity, directness, and control over the generated HTML. Suitable when server-side logic is minimal and mostly concerns fetching and formatting content. - **Full JS Frameworks**: Best suited for complex web applications (dashboards, social media, e-commerce platforms) that require extensive user interaction, real-time updates, and a highly modular, scalable frontend architecture. They abstract away much of the direct DOM manipulation for a more declarative programming style. In essence, the Aki JSON pattern provides a lightweight, "progressive enhancement-like" SPA experience using familiar web technologies, perfect for content sites where the elegance of a full JS framework might be overkill. ### Recent Enhancements and Bug Fixes #### 1. Enhanced Markdown Rendering with Comrak Flags To improve content presentation and authoring flexibility, `lib/ContentRenderer.php` now utilizes several `comrak` flags: - **`--syntax-highlighting base16-ocean.dark`**: Provides code block syntax highlighting. - **`-e footnotes`**: Enables standard Markdown footnotes. - **`--smart`**: Converts ASCII punctuation to typographically correct "smart" punctuation. - **`--gemoji`**: Translates GitHub-style emoji shortcodes (e.g., `:rocket:`) into Unicode emojis (🚀). #### 2. Metadata Extraction and Dynamic SEO `lib/ContentManager.php` and `generate_json.php` were updated to: - Extract `title` and `description` from Markdown files (prioritizing YAML front matter, falling back to first H1 and paragraph snippet). - Include this metadata in the generated JSON. - `index.php`'s JavaScript now uses this metadata to dynamically update `` and `<meta name="description">` tags for better SEO and user experience. #### 3. Browser History Management `index.php`'s JavaScript now integrates the History API, allowing users to use browser back/forward buttons seamlessly. #### 4. Loading Indicators & Improved Error Display Added visual feedback during content loading and more user-friendly error messages for failed fetches. #### 5. **FIXED**: PDF / Gravatar / Iframe Escaping - **Problem**: `iframe` tags (used for PDF and Gravatar embeds) were being HTML-escaped (`<iframe`) in the generated JSON, causing them not to render. - **Cause**: The `--gfm` flag for `comrak` implicitly enables the `tagfilter` extension, which aggressively filters out potentially unsafe HTML tags, even with `--unsafe` enabled. - **Solution**: `lib/ContentRenderer.php` was modified to explicitly enable individual GFM extensions (`strikethrough`, `table`, `autolink`, `tasklist`) but **omitted `tagfilter`**. - **Result**: `iframe` tags (and other raw HTML blocks) now pass through `comrak` unescaped and render correctly. #### 6. **FIXED**: Image Links in Subdirectories - **Problem**: Images were not loading on `envs.net` when `base_path` (`/~username/`) was prepended to image `src` attributes. - **Cause**: The `envs.net` Apache configuration (or similar shared hosting setup) for user subdirectories often implicitly handles `/content/` paths relative to the user's root, meaning explicit prepending of `/~username/` resulted in an incorrect double prefixing or misinterpretation. - **Solution**: The `base_path` prepending logic for `href`/`src` attributes was removed from `lib/ContentRenderer.php`. - **Result**: Images now load correctly. #### 7. **UNRESOLVED**: Heading Rendering Issue in Live Site - **Symptom**: Headings inside `<details>` blocks (e.g., `## Satz-klammer`) appear incorrectly on the live site (e.g., `<h2># Satz-klammer</h2>` or `<h1># Fasnacht Ferien</h1>`). - **Server-side processing**: The `comrak` Markdown processor (as currently configured) passes Markdown inside raw HTML blocks (`<details>`) *literally*. This means the generated JSON contains the raw Markdown (e.g., `## Satz-klammer`), not processed HTML (`<h2>Satz-klammer</h2>`). - **Diagnostic**: The static `debug_static_details.html` file (containing literal `## Satz-klammer` inside `<details>`) renders correctly as plain text (`## Satz-klammer`) in a browser. - **Conclusion**: The incorrect rendering on the live site is **unequivocally caused by client-side JavaScript that is running *after* the page loads and is attempting to re-process the literal Markdown content within the DOM.** This interfering script is incorrectly transforming the literal Markdown into the faulty HTML (`<h2># ...</h2>`). - **Next Steps (User Action)**: 1. **Identify and disable interfering JS**: Use browser developer tools (Network, Sources, Console) to find what other scripts are modifying the DOM or parsing Markdown *after* `index.php`'s JavaScript loads the content. This is the root cause of the incorrect rendering. 2. **Adjust Content Structure**: To ensure headings inside `<details>` render correctly, either: * Write them as raw HTML (`<h2>My Heading</h2>`) directly in the Markdown source. * Or, if client-side Markdown processing is desired, implement a dedicated client-side Markdown parser (e.g., `markdown-it`, `marked.js`) that targets only these specific elements. --- ## Working with the Site ### Adding Content 1. Create a new directory in `content/` (e.g., `content/my-page/`). 2. Create an `index.md` inside that directory. 3. Add a link to the sidebar in `partials/sidebar.php`. ### Updating Content 1. Edit any `.md` file in the `content/` directory. 2. Run `./rebuild.sh` in the terminal. 3. Refresh your browser. ## Environment Compatibility This implementation is specifically tuned for the `envs.net` environment. It automatically detects the user's home directory path to ensure all assets (images, CSS, JS) load correctly regardless of whether the site is accessed via `domain.tld/~user/` or a custom domain.