TKML isn't just a markup language; it's like your retro '90s game console for web apps! No need for CSS or JS—just plug in your components in XML format and play. We've sprinkled in some '90s vibes and a dash of HTTP/1.1 nostalgia to keep things fun and simple.
TKML is designed for building fast, mobile-friendly web applications with minimal configuration. Think of it as your trusty sidekick, providing a set of pre-styled components that follow modern design principles, so you can focus on creating awesome content without sweating the small stuff.
You can create the simplest TKML app by uploading an index.tkml
page to your website. This page serves as the entry point for your application. Here's a basic example:
-
Create an
index.tkml
file: This file will contain your TKML markup. For instance:<title>Hello</title> <desc> Hello world! This is a minimal TKML website. </desc>
-
Upload the file to your server: Place the
index.tkml
file in the root directory of your website or any accessible path. -
Access your TKML app: Go to http://tkml.app, and type
example.com/index.tkml
in input field.
This simple setup will render a page with a title and a description, demonstrating the basic structure of a TKML document.
- 🎨 Pre-styled components with dark/light mode support
- 📱 Mobile-first responsive design
- 🔄 Built-in navigation system with browser history support
- ⚡ Streaming XML parser for fast rendering
- 🎯 Zero CSS/JS configuration needed
- 🔌 Extensible component system
This example demonstrates how to embed a TKML app within your own application
<!DOCTYPE html>
<html>
<head>
<title>TKML App</title>
<link rel="stylesheet" href="./styles.min.css">
<script src="./tkml.min.js"></script>
</head>
<body>
<div id="container"></div>
<script>
const container = document.getElementById('container');
const tkml = new TKML(container, { dark: true });
tkml.load('index.tkml');
</script>
</body>
</html>
Displays a heading.
<title>Regular Title</title>
<title center>Centered Title</title>
Attributes:
center
- Centers the title text
Displays descriptive text in a muted color.
<desc>Description text</desc>
<desc center>Centered description</desc>
Attributes:
center
- Centers the description text
Creates a clickable button.
<button href="/action">Click Me</button>
<button width="200">Fixed Width Button</button>
<button width="100%">Full Width Button</button>
Attributes:
href
- URL to navigate to when clickedtarget
- Target window ('_blank' for new window)preload
- Set to "true" to preload the href URLwidth
- Button width in pixels or percentage (e.g. "200" or "100%")
Creates a text input field.
<input placeholder="Enter text" href="/submit" name="query" />
Attributes:
placeholder
- Placeholder textvalue
- Initial valuetype
- Input type (text, password, etc)href
- URL to submit to on Entername
- Parameter name for the submitted value
Creates a clickable section with optional icon.
<section href="/details" icon="/icons/arrow.png">Section content</section>
Attributes:
href
- URL to navigate to when clickedicon
- URL of the icon to displaytarget
- Target windowpreload
- Set to "true" to preload the href URL
Groups items in a list container.
<list>
<section>Item 1</section>
<section>Item 2</section>
</list>
Another type of list container without any separation between items. The info block always tries to layout elements inside to make them look good.
<info>
<img src="/image.jpg" height="200" />
<title>Title</title>
<desc>Description</desc>
<button href="/action">Action</button>
</info>
Creates a toggle switch.
<checkbox href="/toggle" checked>Toggle me</checkbox>
Attributes:
href
- URL to call when toggledchecked
- Initial checked statetarget
- Target windowpreload
- Set to "true" to preload the href URL
Creates a radio button in a group.
<radio group="options" href="/select" checked>Option 1</radio>
<radio group="options" href="/select">Option 2</radio>
Attributes:
group
- Group name for related radio buttonshref
- URL to call when selectedchecked
- Initial checked statetarget
- Target windowpreload
- Set to "true" to preload the href URL
Displays syntax-highlighted code.
<code lang="javascript">
const x = 42;
console.log(x);
</code>
Attributes:
lang
- Programming language for syntax highlighting
Displays an image.
<img src="/image.jpg" alt="Description" height="200" />
Attributes:
src
- Image URLalt
- Alternative textheight
- Fixed height in pixels
Creates a loading indicator that loads content when visible.
<loader href="/content" />
Attributes:
href
- URL of content to load when loader becomes visible
Creates a clickable link.
<a href="/page" preload="true">Click here</a>
Attributes:
href
- URL to navigate totarget
- Target window ('_blank' for new window)preload
- Set to "true" to preload the href URL
Basic text formatting tags:
<b>Bold text</b>
<i>Italic text</i>
<u>Underlined text</u>
<s>Strikethrough text</s>
Adds vertical spacing:
<br/>
All components that support navigation (button
, section
, a
, etc) have these common attributes:
href
- URL to navigate totarget
- Target window ('_blank' for new window)preload
- Set to "true" to preload the URL
Creates a sticky header that stays at the top while scrolling.
<header>Regular Header</header>
<header center>Centered Header</header>
Attributes:
center
- Centers the header text
The header component is useful for creating navigation bars or section titles that should remain visible while scrolling through content.
Creates a back navigation button. When used inside a header, displays as a round button. When used standalone, displays as a regular button with "Back" text.
<header>
<back href="/previous" />
Page Title
</header>
<!-- Or as standalone button -->
<back href="/home" />
Attributes:
href
- URL to navigate to (defaults to browser's back action if not specified)target
- Target window ('_blank' for new window)preload
- Set to "true" to preload the href URL
Creates a sticky footer that stays at the bottom. Can automatically hide when scrolling down.
<footer>Regular Footer</footer>
<footer autohide>Auto-hiding Footer</footer>
Attributes:
autohide
- Makes the footer hide when scrolling down and show when scrolling up
The footer component is useful for creating navigation bars or action buttons that should remain accessible while scrolling.
Creates a small oval-shaped label. Multiple pills are automatically grouped horizontally.
<pill>Label 1</pill>
<pill>Label 2</pill>
<pill>Label 3</pill>
Pills are useful for displaying tags, categories, or status indicators. When multiple pills are used consecutively, they are automatically arranged horizontally with proper spacing.
Makes text white, useful for highlighting text in descriptions.
<desc>Regular text <w>highlighted text</w> regular text</desc>
Complete page example:
<title center>Welcome</title>
<desc center>Select an option below</desc>
<list>
<section href="/option1" icon="/icons/1.png">First Option</section>
<section href="/option2" icon="/icons/2.png">Second Option</section>
</list>
<info>
<img src="/banner.jpg" height="200" />
<title>Important Info</title>
<desc>Additional details here</desc>
<button href="/more">Learn More</button>
</info>
// Automatically detects system preference
new TKML(container);
// Force dark mode
new TKML(container, { dark: true });
All navigation is handled automatically through href
attributes. The library manages browser history and provides smooth transitions between pages.
- Install dependencies:
npm install
- Start development server with hot reload:
npm run dev
- Build for production:
npm run pack
TKML works in all modern browsers that support:
- XMLHttpRequest
- ES6+ JavaScript
- CSS Custom Properties
- Browser History API
MIT
To automatically wrap .tkml
files in the HTML template when accessed directly, add this to your Nginx configuration:
# Define variable to check if client accepts TKML
map $http_accept $is_tkml {
"application/tkml" 1;
default 0;
}
server {
# ... your other server configuration ...
# Handle .tkml files
location ~ \.tkml$ {
if ($is_tkml = 0) {
# If not requesting TKML directly, transform the response
sub_filter_types application/tkml;
sub_filter_once on;
add_header Content-Type text/html;
sub_filter_types *;
sub_filter '^' '<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://tkml.app/styles.min.css">
<script src="https://tkml.app/tkml.min.js"></script>
</head>
<body>
<div id="container">
<script>
const container = document.getElementById("container");
const tkml = new TKML(container, { dark: true });
tkml.fromText(`';
sub_filter '$' '`);
</script>
</div>
</body>
</html>';
}
# If requesting TKML directly, serve as is
default_type application/tkml;
}
}
This configuration:
- Uses only standard Nginx modules (sub_filter)
- Automatically wraps TKML content when accessed directly in browser
- Serves raw TKML when requested with proper headers
- No additional modules required
The solution works by wrapping the response content in HTML template using sub_filter
directives to add content before and after the TKML file content.
TKML supports several standard HTML tags for text formatting:
<b>Bold text</b>
<i>Italic text</i>
<u>Underlined text</u>
<s>Strikethrough text</s>
These tags work exactly like their HTML counterparts and can be used within any text content. For example:
<desc>
This is <b>bold</b> and this is <i>italic</i>.
You can also <u>underline</u> or <s>strike through</s> text.
These tags can be <b><i>combined</i></b> as needed.
</desc>
<section>
Regular text with <b>bold emphasis</b>
</section>
<title>
Title with <i>italic part</i>
</title>
The tags maintain consistent styling with the rest of your TKML content while providing familiar HTML text formatting options.