webtui+chawan 搭建兼容TUI与HTML的UI
方案
- chawan,支持sixel与kitty graphics protocol的终端浏览器,积极开发中: https://chawan.net/#:~:text=Homebrew
- webtui,仅css的终端主题,严格遵循
ch字符单位长度,易于与chawan集成: https://webtui.ironclad.sh/installation/astro/- astro,轻量编译: https://docs.astro.build/zh-cn/tutorial/2-pages/2/ 。像react, vue(vite)也是模板编译型框架,不过astro更轻量,适合写文档等简单的轻交互界面。也可以后期引入vue等框架,渐进开发。
- mdx,可运行js的markdown: https://docs.astro.build/en/guides/integrations-guide/mdx/
为什么要同时兼容HTML与TUI?
见: https://github.com/webtui/webtui/issues/144
有许多CLI工具,如docker/podman,会同时有webUI与TUI支持,但是2套完全不同的代码。而且大部分情况下,TUI的维护人很少,且不活跃,大多都是昙花一现。这个方案旨在主要支持HTML,但也能完美兼容TUI,不过需要自行安装/编译chawan,毕竟TUI用的人真的挺少,但tty或ssh等fallback情况下就很好用。
教程
astro
markdown文件会直接被astro编译为HTML,URL路由会按照目录结构展开,目录下的index.astro会被视为url入口
keyword: getStaticPaths(), Astro.props, Astro.params, <VueComponent client:load>, <Avatar server:defer />
轻量react框架.jsx: https://preactjs.com/
index.astro
---
// 类似vue中的<script setup>,astro仅在build时运行一次
import '../styles/global.css';
import Navigation from '../components/Navigation.astro';
const jsVar1 = "#000";
const { platform, username } = Astro.props;
---
{jsVar1 && <p>我非常乐意学习 Astro!</p>}
{jsVar2 === true ? <p>我的目标是在三天内完成。</p> : <p>我的目标不是 3 天。</p>}
<style define:vars={{ jsVar1, jsVar2 }}>
<Navigation />
<a href={`https://www.${platform}.com/${username}`}>{platform}</a>
<Social platform="twitter" username="astrodotbuild" />
👇client客户端浏览器运行时会执行,不编译
<script>
import "../scripts/menu.js";
</script>
<slot />
index.md
---
layout: ../../layouts/MarkdownPostLayout.astro
---
index.css
@media screen and (min-width: 636px) {}
:has(.menu[aria-expanded="true"]) .nav-links {
display: unset;
}
html.dark {
background-color: #0d0950;
color: #fff;
}
src/pages/tags/[tag].astro → http://localhost:4321/tags/{params}
---
import BaseLayout from '../../layouts/BaseLayout.astro';
export async function getStaticPaths() {
// const allPosts = Object.values(import.meta.glob('../posts/*.md', { eager: true }));
const allPosts = await Astro.glob('../posts/*.md');
return [
{params: {tag: "astro"}, props: {posts: allPosts}},
{params: {tag: "successes"}, props: {posts: allPosts}},
];
}
const { tag } = Astro.params; //💡 url params
const { posts } = Astro.props;
---
<BaseLayout pageTitle={tag}>
<p>包含「{tag}」标签的文章</p>
</BaseLayout>
{allPosts.map((post: any) => <li><a href={post.url}>{post.frontmatter.title}</a></li>)}
client:
非astro组件才需要加(如.vue, preact.jsx)。
有client: 在客户端上才运行js(.astro内的<script>也是运行时)
无client:XXX:则在编译时确定。
- load: onLoad
- visible: css display: visible;
mdx
webtui兼容包
尝试:<noscript>标签
<style></style>
<noscript><style> /* chawan样式 */ </style></noscript>
缺点是chawan开启js后失效。
js判断UA==chawan,注入css
散记
<script src="..." onerror="this.src='...'" defer />

浙公网安备 33010602011771号