### GET /api/setup Source: https://docs.trmnl.com/go/diy/byos Initializes the device setup process. ```APIDOC ## GET /api/setup ### Description Initializes the device setup process. ### Method GET ### Endpoint http://byos.local/api/setup ### Parameters #### Headers - **ID** (string) - Required - The device MAC address ``` -------------------------------- ### Clone and Setup Django Source: https://trmnl.com/developers Commands to clone the Django repository and install requirements via pip. ```bash gh repo clone usetrmnl/byos_django pip install -r requirements.txt ``` -------------------------------- ### View Implementation Examples Source: https://trmnl.com/framework/docs/3.1/view Examples showing platform-managed view wrapping versus manual view implementation. ```html
...
...
``` ```html
...
...
``` -------------------------------- ### Clone and Setup Next.js Source: https://trmnl.com/developers Commands to clone the Next.js BYOS repository and install dependencies via npm. ```bash gh repo clone usetrmnl/byos_next npm install ``` -------------------------------- ### Setup Device via API Source: https://docs.trmnl.com/go/diy/byos Use this command to initialize the device setup process by providing the device MAC address. ```shell curl "http://byos.local/api/setup" \ -H 'ID: ' \ -H 'Content-Type: application/json' ``` -------------------------------- ### POST /api/setup Source: https://docs.trmnl.com/go/diy/byos Initializes the device setup process. ```APIDOC ## POST /api/setup ### Description Initializes the device setup process for the TRMNL BYOS system. ### Method POST ### Endpoint http://byos.local/api/setup ### Parameters #### Headers - **ID** (string) - Required - The MAC address of the device. ``` -------------------------------- ### Clone and Setup Phoenix Source: https://trmnl.com/developers Commands to clone the Phoenix repository and run the setup script. ```bash gh repo clone usetrmnl/byos_phoenix bin/setup ``` -------------------------------- ### Clone and Setup Terminus Source: https://trmnl.com/developers Commands to clone the Terminus repository and run the setup script. ```bash gh repo clone usetrmnl/terminus bin/setup ``` -------------------------------- ### Setup Error Handling Source: https://trmnl.com/flash Monitors the ESP web install button for browser compatibility errors. ```javascript function setupErrorHandling() { const installButton = document.querySelector("esp-web-install-button"); if (installButton) { customElements.whenDefined('esp-web-install-button').then(() => { const checkForError = () => { const shadowText = installButton.shadowRoot?.textContent?.trim(); if (shadowText?.includes('Your browser does not support')) { showError(shadowText); installButton.style.display = 'none'; return true; } return false; }; if (!checkForError()) { setTimeout(checkForError, 25); setTimeout(checkForError, 200); } }); } } ``` -------------------------------- ### Clone and Setup Inker Source: https://trmnl.com/developers Commands to clone the Inker repository and start the service using Docker Compose. ```bash gh repo clone usetrmnl/inker docker compose up -d --build ``` -------------------------------- ### Responsive Grid Wrapping Examples Source: https://trmnl.com/framework/docs/3.1/grid Examples demonstrating how to use grid--wrap in combination with different minimum column sizes to control responsive behavior. ```html
Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
``` ```html
Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
``` -------------------------------- ### Manage Example Rendering Guards Source: https://trmnl.com/framework/docs/3.1/pixel_perfect Utility functions to check for pending example wrappers and guard the parent terminalization process. ```javascript function hasPendingExampleWrappers() { return Array.from(document.querySelectorAll('.trmnl-example')).some((wrapper) => { return wrapper.dataset.trmnlWrapped !== 'true'; }); } function shouldRunParentTerminalize() { if (window.__TRMNL_FRAMEWORK_PARENT_TERMINALIZE__ === false) return false; if (hasPendingExampleWrappers()) return false; return !!document.querySelector('#main-content .screen'); } function installParentTerminalizeGuard() { if (typeof window.executeTerminalize === 'function' && !window.executeTerminalize.__frameworkDocsGuard) { const originalExecuteTerminalize = window.executeTerminalize; window.executeTerminalize = function() { if (isDocsOrExamplesPage() && !shouldRunParentTerminalize()) return; ``` -------------------------------- ### Validate Device Friendly ID Source: https://trmnl.com/signup Checks if the input device ID matches a restricted example value and alerts the user if so. Clears the input field upon detection of the example ID. ```javascript function checkFriendlyId() { if (user_device_friendly_id.value.toUpperCase() == '783E4C') { alert("Oh hi there, that's an example ID from the inside of your box. Follow those steps to get yours."); user_device_friendly_id.value = ''; } } ``` -------------------------------- ### Clone and Setup LaraPaper Source: https://trmnl.com/developers Commands to clone the LaraPaper repository and install dependencies via Composer. ```bash gh repo clone usetrmnl/larapaper composer install ``` -------------------------------- ### Initialize Framework Runtime Source: https://trmnl.com/framework/docs/3.1/responsive_test Bootstraps the documentation environment, including TOC generation, scroll restoration, and syntax highlighting. ```javascript var frameworkDocsRuntime = window.__frameworkDocsRuntime || (window.__frameworkDocsRuntime = {}); function isDocsOrExamplesPage() { return window.location.pathname.indexOf('/framework/docs') === 0 || window.location.pathname.indexOf('/framework/examples') === 0; } function addPreviewClassToScreens(rootDocument) { if (!isDocsOrExamplesPage() || !rootDocument) return; try { rootDocument.querySelectorAll('.screen').forEach((screen) => { screen.classList.add('screen--preview'); }); } catch(_) {} } // Persist left sidebar scroll position across full page navigations (function setupLeftSidebarScrollPersistence() { if (frameworkDocsRuntime.sidebarScrollPersistence) return; const STORAGE_KEY = 'frameworkLeftSidebarScroll'; function saveLeftSidebarScroll() { try { const el = document.getElementById('left-sidebar-nav'); if (el) sessionStorage.setItem(STORAGE_KEY, String(el.scrollTop)); } catch(_) {} } window.addEventListener('pagehide', saveLeftSidebarScroll); window.addEventListener('beforeunload', saveLeftSidebarScroll); frameworkDocsRuntime.sidebarScrollPersistence = true; })(); function bootFramework() { installParentTerminalizeGuard(); addPreviewClassToScreens(document); // Initialize TOC generation generateTableOfContents(); // Restore left sidebar scroll position after layout settles (function restoreLeftSidebarScroll() { try { const saved = sessionStorage.getItem('frameworkLeftSidebarScroll'); if (saved) { const el = document.getElementById('left-sidebar-nav'); if (el) { requestAnimationFrame(function() { requestAnimationFrame(function() { el.scrollTop = parseInt(saved, 10) || 0; }); }); } } } catch(_) {} })(); // Initialize sticky border radius handler initStickyBorderRadius(); // Update active state in left sidebar links updateActiveSidebarLinks(); runTerminalizeWhenExamplesReady(); // Syntax highlighting for code examples try { if (typeof Prism !== 'undefined') { const mainContent = document.getElementById('main-content'); if (mainContent) { Prism.highlightAllUnder(mainContent); } else { Prism.highlightAll(); } } } catch(e) {} } ``` -------------------------------- ### Initialize Framework Documentation Utilities Source: https://trmnl.com/framework Contains the core logic for booting the framework, managing sidebar active states, and guarding terminalization execution. ```javascript isDocsOrExamplesPage() { return window.location.pathname.indexOf('/framework/docs') === 0 || window.location.pathname.indexOf('/framework/examples') === 0; } function addPreviewClassToScreens(rootDocument) { if (!isDocsOrExamplesPage() || !rootDocument) return; try { rootDocument.querySelectorAll('.screen').forEach((screen) => { screen.classList.add('screen--preview'); }); } catch(_) {} } function bootFramework() { installParentTerminalizeGuard(); addPreviewClassToScreens(document); // Initialize TOC generation generateTableOfContents(); // Update active state in left sidebar links updateActiveSidebarLinks(); runTerminalizeWhenExamplesReady(); // Syntax highlighting for code examples try { if (typeof Prism !== 'undefined') { const mainContent = document.getElementById('main-content'); if (mainContent) { Prism.highlightAllUnder(mainContent); } else { Prism.highlightAll(); } } } catch(e) {} } function hasPendingExampleWrappers() { return Array.from(document.querySelectorAll('.trmnl-example')).some((wrapper) => { return wrapper.dataset.trmnlWrapped !== 'true'; }); } function shouldRunParentTerminalize() { if (window.__TRMNL_FRAMEWORK_PARENT_TERMINALIZE__ === false) return false; if (hasPendingExampleWrappers()) return false; return !!document.querySelector('#main-content .screen'); } function installParentTerminalizeGuard() { if (typeof window.executeTerminalize === 'function' && !window.executeTerminalize.__frameworkDocsGuard) { const originalExecuteTerminalize = window.executeTerminalize; window.executeTerminalize = function() { if (isDocsOrExamplesPage() && !shouldRunParentTerminalize()) return; return originalExecuteTerminalize.apply(this, arguments); }; window.executeTerminalize.__frameworkDocsGuard = true; } if (typeof window.terminalize === 'function' && !window.terminalize.__frameworkDocsGuard) { const originalTerminalize = window.terminalize; window.terminalize = function() { if (isDocsOrExamplesPage() && !shouldRunParentTerminalize()) return; return originalTerminalize.apply(this, arguments); }; window.terminalize.__frameworkDocsGuard = true; } } function executeParentTerminalizeNow() { if (!shouldRunParentTerminalize()) return; try { if (typeof markFrameworkReady === 'function') { markFrameworkReady(); } else { window.frameworkReady = true; } } catch(e) {} const runTerminalizePipeline = () => { try { if (typeof executeTerminalize === 'function') { executeTerminalize(); } else if (typeof terminalize === 'function') { terminalize(); } } catch(e) {} }; runTerminalizePipeline(); } function runTerminalizeWhenExamplesReady() { if (frameworkDocsRuntime.examplesWrappedHandler) { document.removeEventListener('trmnl:framework-examples:wrapped', frameworkDocsRuntime.examplesWrappedHandler); frameworkDocsRuntime.examplesWrappedHandler = null; } if (frameworkDocsRuntime.examplesWrappedTimeout) { clearTimeout(frameworkDocsRuntime.examplesWrappedTimeout); frameworkDocsRuntime.examplesWrappedTimeout = null; } const run = () => { if (frameworkDocsRuntime.examplesWrappedHandler) { document.removeEventListener('trmnl:framework-examples:wrapped', frameworkDocsRuntime.examplesWrappedHandler); frameworkDocsRuntime.examplesWrappedHandler = null; } if (frameworkDocsRuntime.examplesWrappedTimeout) { clearTimeout(frameworkDocsRuntime.examplesWrappedTimeout); frameworkDocsRuntime.examplesWrappedTimeout = null; } executeParentTerminalizeNow(); }; if (!hasPendingExampleWrappers()) { run(); return; } frameworkDocsRuntime.examplesWrappedHandler = function() { if (!hasPendingExampleWrappers()) run(); }; document.addEventListener('trmnl:framework-examples:wrapped', frameworkDocsRuntime.examplesWrappedHandler); frameworkDocsRuntime.examplesWrappedTimeout = setTimeout(frameworkDocsRuntime.examplesWrappedHandler, 2000); } function updateActiveSidebarLinks() { const leftSidebar = document.getElementById('left-sidebar'); if (!leftSidebar) return; const links = leftSidebar.querySelectorAll('a[href]'); const currentPath = window.location.pathname; links.forEach(a => { try { const isActive = a.pathname === currentPath; a.classList.toggle('bg-primary-100', isActive); a.classList.toggle('dark:bg-primary-900/30', isActive); a.classList.toggle('text-primary-700', isActive); a.classList.toggle('dark:text-primary-400', isActive); a.classList.toggle('font-medium', isActive); a.classList.toggle('text-gray-700', !isActive); a.classList.toggle('dark:text-gray-300', !isActive); a.classList.toggle('hover:bg-gray-200', !isActive); a.classList.toggle('dark:hover:bg-gray-700', !isActive); } catch(e) {} }); } if (frameworkDocsRuntime.bootFramework) { document.removeEventListener('DOMContentLoaded', frameworkDocsRuntime.bootFramework); document.removeEventListener('turbo:load', frameworkDocsRuntime.bootFramework); } installParentTerminalizeGuard(); frameworkDocsRuntime.bootFramework = bootFramework; document.addEventListener('DOMContentLoaded', frameworkDocsRuntime.bootFramework); document.addEventListener('turbo:load', ``` -------------------------------- ### Initialize Framework Runtime Source: https://trmnl.com/framework/docs/3.1/colors Bootstraps the documentation environment, including syntax highlighting, sidebar state restoration, and terminalization guards. ```javascript var frameworkDocsRuntime = window.__frameworkDocsRuntime || (window.__frameworkDocsRuntime = {}); function isDocsOrExamplesPage() { return window.location.pathname.indexOf('/framework/docs') === 0 || window.location.pathname.indexOf('/framework/examples') === 0; } function addPreviewClassToScreens(rootDocument) { if (!isDocsOrExamplesPage() || !rootDocument) return; try { rootDocument.querySelectorAll('.screen').forEach((screen) => { screen.classList.add('screen--preview'); }); } catch(_) {} } // Persist left sidebar scroll position across full page navigations (function setupLeftSidebarScrollPersistence() { if (frameworkDocsRuntime.sidebarScrollPersistence) return; const STORAGE_KEY = 'frameworkLeftSidebarScroll'; function saveLeftSidebarScroll() { try { const el = document.getElementById('left-sidebar-nav'); if (el) sessionStorage.setItem(STORAGE_KEY, String(el.scrollTop)); } catch(_) {} } window.addEventListener('pagehide', saveLeftSidebarScroll); window.addEventListener('beforeunload', saveLeftSidebarScroll); frameworkDocsRuntime.sidebarScrollPersistence = true; })(); function bootFramework() { installParentTerminalizeGuard(); addPreviewClassToScreens(document); // Initialize TOC generation generateTableOfContents(); // Restore left sidebar scroll position after layout settles (function restoreLeftSidebarScroll() { try { const saved = sessionStorage.getItem('frameworkLeftSidebarScroll'); if (saved) { const el = document.getElementById('left-sidebar-nav'); if (el) { requestAnimationFrame(function() { requestAnimationFrame(function() { el.scrollTop = parseInt(saved, 10) || 0; }); }); } } } catch(_) {} })(); // Update active state in left sidebar links updateActiveSidebarLinks(); runTerminalizeWhenExamplesReady(); // Syntax highlighting for code examples try { if (typeof Prism !== 'undefined') { const mainContent = document.getElementById('main-content'); if (mainContent) { Prism.highlightAllUnder(mainContent); } else { Prism.highlightAll(); } } } catch(e) {} } function hasPendingExampleWrappers() { return Array.from(document.querySelectorAll('.trmnl-example')).some((wrapper) => { return wrapper.dataset.trmnlWrapped !== 'true'; }); } function shouldRunParentTerminalize() { if (window.__TRMNL_FRAMEWORK_PARENT_TERMINALIZE__ === false) return false; if (hasPendingExampleWrappers()) return false; return !!document.querySelector('#main-content .screen'); } function installParentTerminalizeGuard() { if (typeof window.executeTerminalize === 'function' && !window.executeTerminalize.__frameworkDocsGuard) { const originalExecuteTerminalize = window.executeTerminalize; window.executeTerminalize = function() { if (isDocsOrExamplesPage() && !shouldRunParentTerminalize()) return; return originalExecuteTerminalize.apply(this, arguments); }; window.executeTerminalize.__frameworkDocsGuard = true; } if (typeof window.terminalize === 'function' && !window.terminalize.__frameworkDocsGuard) { const originalTerminalize = window.terminalize; window.terminalize = function() { if (isDocsOrExamplesPage() && !shouldRunParentTerminalize()) return; return originalTerminalize.apply(this, arguments); }; window.terminalize.__frameworkDocsGuard = true; } } function executeParentTerminalizeNow() { if (!shouldRunParentTerminalize()) return; try { if (typeof markFrameworkReady === 'function') { markFrameworkReady(); } else { window.frameworkReady = true; } } catch(e) {} const runTerminalizePipeline = () => { try { if (typeof executeTerminalize === 'function') { executeTerminalize(); } else if (typeof terminalize === 'function') { terminalize(); } } catch(e) {} }; runTerminalizePipeline(); } function runTerminalizeWhenExamplesReady() { if (frameworkDocsRuntime.examplesWrappedHandler) { document.removeEventListener('trmnl:framework-examples:wrapped', frameworkDocsRuntime.examplesWrappedHandler); frameworkDocsRuntime.examplesWrappedHandler = null; } if (frameworkDocsRuntime.examplesWrappedTimeout) { clearTimeout(frameworkDocsRuntime.examplesWrappedTimeout); frameworkDocsRuntime.examplesWrappedTimeout = null; } const run = () => { if (frameworkDocsRuntime.examplesWrappedHandler) { document.removeEventListener('trmnl:framework-examples:wrapped', frameworkDocsRuntime.examplesWrappedHandler); frameworkDocsRuntime.examplesWrappedHandler = ``` -------------------------------- ### Get merge variable content via GET Source: https://docs.trmnl.com/trmnl-internal-documentation/custom-plugins/create-a-screen Fetch existing merge_variables from a private plugin by performing a GET request to the webhook endpoint. ```http GET /api/v1/webhook/YOUR_UUID ``` -------------------------------- ### Initialize Firmware Environment Source: https://trmnl.com/flash Sets up the initial state by fetching firmware releases and initializing UI components upon DOM content load. ```javascript :root { --esp-tools-button-color: #f8654b; --esp-tools-button-text-color: #ffffff; --esp-tools-button-border-radius: .5rem; } var firmwareReleases; const customMode = false; document.addEventListener('DOMContentLoaded', async () => { firmwareReleases = await $.ajax('/firmware/releases.json'); initModels(); setupErrorHandling(); }) ``` -------------------------------- ### Setup Device API Source: https://docs.trmnl.com/go/diy/byos Initializes the device connection using the device's MAC address. ```bash curl "http://byos.local/api/setup" \ -H 'ID: ' \ -H 'Content-Type: application/json' ``` -------------------------------- ### Initialize Framework Runtime Source: https://trmnl.com/framework/docs/3.1/gap Contains the core runtime setup including sidebar scroll persistence, screen preview class injection, and framework booting logic. ```javascript var frameworkDocsRuntime = window.__frameworkDocsRuntime || (window.__frameworkDocsRuntime = {}); function isDocsOrExamplesPage() { return window.location.pathname.indexOf('/framework/docs') === 0 || window.location.pathname.indexOf('/framework/examples') === 0; } function addPreviewClassToScreens(rootDocument) { if (!isDocsOrExamplesPage() || !rootDocument) return; try { rootDocument.querySelectorAll('.screen').forEach((screen) => { screen.classList.add('screen--preview'); }); } catch(_) {} } // Persist left sidebar scroll position across full page navigations (function setupLeftSidebarScrollPersistence() { if (frameworkDocsRuntime.sidebarScrollPersistence) return; const STORAGE_KEY = 'frameworkLeftSidebarScroll'; function saveLeftSidebarScroll() { try { const el = document.getElementById('left-sidebar-nav'); if (el) sessionStorage.setItem(STORAGE_KEY, String(el.scrollTop)); } catch(_) {} } window.addEventListener('pagehide', saveLeftSidebarScroll); window.addEventListener('beforeunload', saveLeftSidebarScroll); frameworkDocsRuntime.sidebarScrollPersistence = true; })(); function bootFramework() { installParentTerminalizeGuard(); addPreviewClassToScreens(document); // Initialize TOC generation generateTableOfContents(); // Restore left sidebar scroll position after layout settles (function restoreLeftSidebarScroll() { try { const saved = sessionStorage.getItem('frameworkLeftSidebarScroll'); if (saved) { const el = document.getElementById('left-sidebar-nav'); if (el) { requestAnimationFrame(function() { requestAnimationFrame(function() { el.scrollTop = parseInt(saved, 10) || 0; }); }); } } } catch(_) {} })(); // Update active state in left sidebar links updateActiveSidebarLinks(); runTerminalizeWhenExamplesReady(); // Syntax highlighting for code examples try { if (typeof Prism !== 'undefined') { const mainContent = document.getElementById('main-content'); if (mainContent) { Prism.highlightAllUnder(mainContent); } else { Prism.highlightAll(); } } } catch(e) {} } function hasPendingExampleWrappers() { return Array.from(document.querySelectorAll('.trmnl-example')).some((wrapper) => { return wrapper.dataset.trmnlWrapped !== 'true'; }); } function shouldRunParentTerminalize() { if (window.__TRMNL_FRAMEWORK_PARENT_TERMINALIZE__ === false) return false; if (hasPendingExampleWrappers()) return false; return !!document.querySelector('#main-content .screen'); } function installParentTerminalizeGuard() { if (typeof window.executeTerminalize === 'function' && !window.executeTerminalize.__frameworkDocsGuard) { const originalExecuteTerminalize = window.executeTerminalize; window.executeTerminalize = function() { if (isDocsOrExamplesPage() && !shouldRunParentTerminalize()) return; return originalExecuteTerminalize.apply(this, arguments); }; window.executeTerminalize.__frameworkDocsGuard = true; } if (typeof window.terminalize === 'function' && !window.terminalize.__frameworkDocsGuard) { const originalTerminalize = window.terminalize; window.terminalize = function() { if (isDocsOrExamplesPage() && !shouldRunParentTerminalize()) return; return originalTerminalize.apply(this, arguments); }; window.terminalize.__frameworkDocsGuard = true; } } function executeParentTerminalizeNow() { if ``` -------------------------------- ### Manage Example Wrappers Source: https://trmnl.com/framework/docs/3.1/scale Ensures that terminalization logic only runs after all example wrappers have been processed, with a fallback timeout. ```javascript function runTerminalizeWhenExamplesReady() { if (frameworkDocsRuntime.examplesWrappedHandler) { document.removeEventListener('trmnl:framework-examples:wrapped', frameworkDocsRuntime.examplesWrappedHandler); frameworkDocsRuntime.examplesWrappedHandler = null; } if (frameworkDocsRuntime.examplesWrappedTimeout) { clearTimeout(frameworkDocsRuntime.examplesWrappedTimeout); frameworkDocsRuntime.examplesWrappedTimeout = null; } const run = () => { if (frameworkDocsRuntime.examplesWrappedHandler) { document.removeEventListener('trmnl:framework-examples:wrapped', frameworkDocsRuntime.examplesWrappedHandler); frameworkDocsRuntime.examplesWrappedHandler = null; } if (frameworkDocsRuntime.examplesWrappedTimeout) { clearTimeout(frameworkDocsRuntime.examplesWrappedTimeout); frameworkDocsRuntime.examplesWrappedTimeout = null; } executeParentTerminalizeNow(); }; if (!hasPendingExampleWrappers()) { run(); return; } frameworkDocsRuntime.examplesWrappedHandler = function() { if (!hasPendingExampleWrappers()) run(); }; document.addEventListener('trmnl:framework-examples:wrapped', frameworkDocsRuntime.examplesWrappedHandler); frameworkDocsRuntime.examplesWrappedTimeout = setTimeout(frameworkDocsRuntime.examplesWrappedHandler, 2000); } ``` -------------------------------- ### Initialize Framework Runtime Source: https://trmnl.com/framework/docs/3.1/clamp Bootstraps the framework by setting up event listeners for DOMContentLoaded and Turbo load events. ```javascript if (frameworkDocsRuntime.bootFramework) { document.removeEventListener('DOMContentLoaded', frameworkDocsRuntime.bootFramework); document.removeEventListener('turbo:load', frameworkDocsRuntime.bootFramework); } installParentTerminalizeGuard(); frameworkDocsRuntime.bootFramework = bootFramework; document.addEventListener('DOMContentLoaded', frameworkDocsRuntime.bootFramework); document.addEventListener('turbo:load', frameworkDocsRuntime.bootFramework); ``` -------------------------------- ### Example xhrSelectSearch Responses Source: https://help.trmnl.com/en/articles/10513740-custom-plugin-form-builder Example JSON responses for the xhrSelectSearch endpoint based on different query parameters. ```ruby # https://trmnl.com/custom_plugin_example_xhr_select_search.json​ # query=null [ { 'id' => 'db-123', 'name' => 'Project Tasks' }, { 'id' => 'db-456', 'name' => 'Team Goals' }, { 'id' => 'db-789', 'name' => 'Family Goals' } ] # query=goa [ { 'id' => 'db-456', 'name' => 'Team Goals' }, { 'id' => 'db-789', 'name' => 'Family Goals' } ] ``` -------------------------------- ### Reusable Liquid Template Example Source: https://docs.trmnl.com/go/reusing-markup A basic example of a Liquid template structure used for rendering content. ```liquid {% include 'header' %}

{{ title }}

{{ body }}

{% include 'footer' %} ``` -------------------------------- ### Google Drive Image URL Example Source: https://trmnl.com/llms-full.txt Example of a shareable link format for images hosted on Google Drive. ```text https://drive.google.com/file/d/164qYbGtnzQq_PDLE-eB6cu4a6mIT8DzN/view?usp=sharing ``` -------------------------------- ### Initialize Framework Runtime Source: https://trmnl.com/framework/docs/3.1/chart Bootstraps the framework documentation environment and manages event listeners for page lifecycle events. ```javascript (!hasPendingExampleWrappers()) run(); }; document.addEventListener('trmnl:framework-examples:wrapped', frameworkDocsRuntime.examplesWrappedHandler); frameworkDocsRuntime.examplesWrappedTimeout = setTimeout(frameworkDocsRuntime.examplesWrappedHandler, 2000); } function updateActiveSidebarLinks() { const leftSidebar = document.getElementById('left-sidebar'); if (!leftSidebar) return; const links = leftSidebar.querySelectorAll('a[href]'); const currentPath = window.location.pathname; links.forEach(a => { try { const isActive = a.pathname === currentPath; a.classList.toggle('bg-primary-100', isActive); a.classList.toggle('dark:bg-primary-900/30', isActive); a.classList.toggle('text-primary-700', isActive); a.classList.toggle('dark:text-primary-400', isActive); a.classList.toggle('font-medium', isActive); a.classList.toggle('text-gray-700', !isActive); a.classList.toggle('dark:text-gray-300', !isActive); a.classList.toggle('hover:bg-gray-200', !isActive); a.classList.toggle('dark:hover:bg-gray-700', !isActive); } catch(e) {} }); } if (frameworkDocsRuntime.bootFramework) { document.removeEventListener('DOMContentLoaded', frameworkDocsRuntime.bootFramework); document.removeEventListener('turbo:load', frameworkDocsRuntime.bootFramework); } installParentTerminalizeGuard(); frameworkDocsRuntime.bootFramework = bootFramework; document.addEventListener('DOMContentLoaded', frameworkDocsRuntime.bootFramework); document.addEventListener('turbo:load', frameworkDocsRuntime.bootFramework); ``` -------------------------------- ### Track Example Viewport Position Source: https://trmnl.com/framework/docs/3.1/clamp Calculates which documentation example is currently centered in the viewport to support scroll restoration. ```javascript window.getCurrentExamplePosition = function() { // If user is near the top of the page, don't restore scroll position const scrollTop = window.pageYOffset || document.documentElement.scrollTop; const isNearTop = scrollTop < 200; // Within 200px of the top if (isNearTop) { return null; // Don't restore position when at top of page } const examples = document.querySelectorAll('iframe[data-trmnl-example]'); if (examples.length === 0) return null; const viewportHeight = window.innerHeight; const viewportCenter = scrollTop + (viewportHeight / 2); let closestExample = null; let closestDistance = Infinity; let exampleIndex = -1; // Find the example closest to the center of the viewport examples.forEach((example, index) => { const rect = example.getBoundingClientRect(); const exampleTop = scrollTop + rect.top; const exampleCenter = exampleTop + ``` -------------------------------- ### Initialize Framework Runtime Source: https://trmnl.com/framework/docs/3.1/fit_value Handles the initial framework boot sequence and terminalization pipeline. ```javascript (!shouldRunParentTerminalize()) return; try { if (typeof markFrameworkReady === 'function') { markFrameworkReady(); } else { window.frameworkReady = true; } } catch(e) {} const runTerminalizePipeline = () => { try { if (typeof executeTerminalize === 'function') { executeTerminalize(); } else if (typeof terminalize === 'function') { terminalize(); } } catch(e) {} }; runTerminalizePipeline(); } ``` -------------------------------- ### Liquid Template Syntax Examples Source: https://help.trmnl.com/en/articles/9510536-private-plugins Examples of Liquid templating syntax used for plugin markup and variable interpolation. ```liquid {{ text | truncate: 15 }} ``` ```liquid {{ trmnl }} ``` ```liquid {{ IDX_0.field_name }} ``` ```liquid {{ IDX_1.field_name }} ``` ```liquid {{ IDX_0.name }} ``` ```liquid {{ IDX_0.status }} ``` ```liquid {{ field_name }} ``` -------------------------------- ### Initialize Responsive Test Runtime Source: https://trmnl.com/framework/docs/3.1/responsive_test Sets up the runtime environment, including event delegation and BroadcastChannel listeners for cross-window synchronization. ```javascript const responsiveTestRuntime = window.__responsiveTestRuntime__ || { initialized: false, listenersBound: false, lastPath: null }; window.__responsiveTestRuntime__ = responsiveTestRuntime; let responsiveTestChannel = null; function handleResponsiveTestDelegatedClick(e) { const configBtn = e.target.closest('.test-config-btn'); if (configBtn) { handleTestConfigClick(e); return; } const sizeBtn = e.target.closest('.example-size-btn'); if (sizeBtn) { handleExampleSizeClick(e); } } // Function to initialize all responsive test functionality function initializeResponsiveTest() { if (responsiveTestRuntime.initialized && responsiveTestRuntime.lastPath === window.location.pathname) { return; } // Clean up existing channel if any if (responsiveTestChannel) { responsiveTestChannel.close(); } // Set up BroadcastChannel listener for updates from nav screen picker responsiveTestChannel = new BroadcastChannel('screen_picker_framework'); responsiveTestChannel.onmessage = (event) => { const { data } = event; // Only process messages from the nav screen picker, not from ourselves if (data.source === 'responsive_test') { return; } // Only process messages from screen_picker source if (data.source !== 'screen_picker') { return; } // Update local config based on the broadcast if (data.type === 'screenChanged') { // Parse the incoming data const parsedState = parseResponsiveTestStateFromPickerPayload(data); window.__responsiveTestModelKeyname__ = parsedState.keyname; testConfig.bitDepth = parsedState.bitDepth; testConfig.orientation = parsedState.orientation; testConfig.size = parsedState.size; testConfig.densityClass = parsedState.densityClass; testConfig.darkMode = !!parsedState.darkMode; // Update UI without broadcasting back updateTestConfigUI(); // Don't broadcast to prevent feedback loop applyTestConfig(false); // Re-apply sample/original sizing after picker-driven class updates. ``` -------------------------------- ### Text Size Variant Examples Source: https://trmnl.com/framework/docs/3.1/text_size Examples of applying responsive, orientation, and bit-depth prefixes to text size utility classes. ```html Responsive text sizing Larger on 4-bit displays ``` -------------------------------- ### Initialize Framework Documentation Runtime Source: https://trmnl.com/framework/docs/3.1 Configures the environment for documentation pages by disabling Turbo for framework links and setting up the runtime object. ```javascript // ensures all Framework docs load as intended, with terminalize() being invoked Array.from(document.querySelectorAll('[href*="/framework/"]')).forEach(docs => { docs.dataset.turbo = false; }) ``` ```javascript var frameworkDocsRuntime = window.__frameworkDocsRuntime || (window.__frameworkDocsRuntime = {}); function isDocsOrExamplesPage() { return window.location.pathname.indexOf('/framework/docs') === 0 || window.location.pathname.indexOf('/framework/examples') === 0; } function addPreviewClassToScreens(rootDocument) { if (!isDocsOrExamplesPage() || !rootDocument) return; try { rootDocument.querySelectorAll('.screen').forEach((screen) => { screen.classList.add('screen--preview'); }); } catch(_) {} } function bootFramework() { installParentTerminalizeGuard(); addPreviewClassToScreens(document); // Initialize TOC generation generateTableOfContents(); // Update active state in left sidebar links updateActiveSidebarLinks(); runTerminalizeWhenExamplesReady(); // Syntax highlighting for code examples try { if (typeof Prism !== 'undefined') { const mainContent = document.getElementById('main-content'); if (mainContent) { Prism.highlightAllUnder(mainContent); } else { Prism.highlightAll(); } } } catch(e) {} } function hasPendingExampleWrappers() { return Array.from(document.querySelectorAll('.trmnl-example')).some((wrapper) => { return wrapper.dataset.trmnlWrapped !== 'true'; }); } function shouldRunParentTerminalize() { if (window.__TRMNL_FRAMEWORK_PARENT_TERMINALIZE__ === false) return false; if (hasPendingExampleWrappers()) return false; return !!document.querySelector('#main-content .screen'); } function installParentTerminalizeGuard() { if (typeof window.executeTerminalize === 'function' && !window.executeTerminalize.__frameworkDocsGuard) { const originalExecuteTerminalize = window.executeTerminalize; window.executeTerminalize = function() { if (isDocsOrExamplesPage() && !shouldRunParentTerminalize()) return; return originalExecuteTerminalize.apply(this, arguments); }; window.executeTerminalize.__frameworkDocsGuard = true; } if (typeof window.terminalize === 'function' && !window.terminalize.__frameworkDocsGuard) { const originalTerminalize = window.terminalize; window.terminalize = function() { if (isDocsOrExamplesPage() && !shouldRunParentTerminalize()) return; return originalTerminalize.apply(this, arguments); }; window.terminalize.__frameworkDocsGuard = true; } } function executeParentTerminalizeNow() { if (!shouldRunParentTerminalize()) return; try { if (typeof markFrameworkReady === 'function') { markFrameworkReady(); } else { window.frameworkReady = true; } } catch(e) {} const runTerminalizePipeline = () => { try { if (typeof executeTerminalize === 'function') { executeTerminalize(); } else if (typeof terminalize === 'function') { terminalize(); } } catch(e) {} }; runTerminalizePipeline(); } function runTerminalizeWhenExamplesReady() { if (frameworkDocsRuntime.examplesWrappedHandler) { document.removeEventListener('trmnl:framework-examples:wrapped', frameworkDocsRuntime.examplesWrappedHandler); frameworkDocsRuntime.examplesWrappedHandler = null; } if (frameworkDocsRuntime.examplesWrappedTimeout) { clearTimeout(frameworkDocsRuntime.examplesWrappedTimeout); frameworkDocsRuntime.examplesWrappedTimeout = null; } const run = () => { if (frameworkDocsRuntime.examplesWrappedHandler) { document.removeEventListener('trmnl:framework-examples:wrapped', frameworkDocsRuntime.examplesWrappedHandler); frameworkDocsRuntime.examplesWrappedHandler = null; } if (frameworkDocsRuntime.examplesWrappedTimeout) { clearTimeout(frameworkDocsRuntime.examplesWrappedTimeout); frameworkDocsRuntime.examplesWrappedTimeout = null; } executeParentTerminalizeNow(); }; if (!hasPendingExampleWrappers()) { run(); return; } frameworkDocsRuntime.examplesWrappedHandler = function() { if (!hasPendingExampleWrappers()) run(); }; document.addEventListener('trmnl:framework-examples:wrapped', frameworkDocsRuntime.examplesWrappedHandler); frameworkDocsRuntime.examplesWrappedTimeout = setTimeout(frameworkDocsRuntime.examplesWrappedHandler, 2000); } function updateActiveSidebarLinks() { const leftSidebar = document.getElementById('left-sidebar'); if (!leftSidebar) return; const links = leftSidebar.querySelectorAll('a[href]'); const currentPath = window.location.pathname; links.forEach(a => { try { const isActive = a.pathname === currentPath; a.classList.toggle('bg-primary-100', isActive); a.classList.toggle('dark:bg-primary-900/30', isActive); a.classList.toggle('text-primary-700', isActive); ``` -------------------------------- ### Apply Responsive Min/Max and Container Query Sizes Source: https://trmnl.com/llms-full.txt Demonstrates responsive constraints and container query units for dynamic sizing. ```html
Responsive Min Width
Responsive Container Query
```