Styling part one

This commit is contained in:
2026-01-16 14:09:44 +01:00
parent 2a7f123ef2
commit f89ba99587
4 changed files with 353 additions and 87 deletions

208
css/tuivision.css Normal file
View File

@@ -0,0 +1,208 @@
/* TurboVision-inspired integration layer for TuiCSS.
* Keep changes template-owned (do not edit _vendor/tuicss).
*/
/* Base look */
body.luxtools-tv {
min-height: 100vh;
color: #fff;
text-align: left;
padding-top: 34px; /* space for fixed top bar */
}
/* DokuWiki default template tends to assume dark-on-light; override minimal bits */
body.luxtools-tv .dokuwiki {
color: inherit;
}
body.luxtools-tv a {
color: rgb(0, 255, 255);
}
/* Keep the existing centered/max-width layout */
body.luxtools-tv #dokuwiki__site {
background: transparent;
}
/* --- Top bar --- */
#dokuwiki__header {
margin: 0;
}
#luxtools__topbar {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 100;
}
#luxtools__topbar .luxtools__topbar-inner {
display: flex;
align-items: center;
gap: 12px;
}
#luxtools__topbar .luxtools__brand a {
display: inline-flex;
align-items: center;
gap: 8px;
text-decoration: none;
color: black;
}
#luxtools__topbar .luxtools__logo {
width: 18px;
height: 18px;
image-rendering: pixelated;
}
#luxtools__topbar .luxtools__title {
font-weight: bold;
}
#luxtools__topbar .luxtools__search {
margin-left: auto;
display: flex;
justify-content: flex-end;
}
/* Make the core search form look like TuiCSS input */
#luxtools__topbar form.search {
margin: 0;
}
/* Trace should be inline in the bar (not centered, not blocky) */
#luxtools__topbar .luxtools__trace {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 45vw;
color: black;
}
#luxtools__topbar .luxtools__trace .breadcrumbs {
display: inline;
margin: 0;
}
#luxtools__topbar .luxtools__trace a {
color: black;
}
#luxtools__topbar form.search input[type="text"],
#luxtools__topbar form.search input#qsearch__in {
background-color: rgb(0, 0, 0);
color: white;
outline: 0;
border: none;
border-radius: 0;
padding: 2px 6px;
width: 100%;
max-width: 26em;
}
#luxtools__topbar form.search input[type="text"]:focus,
#luxtools__topbar form.search input#qsearch__in:focus {
background-color: rgb(255, 255, 0);
color: black;
}
#luxtools__topbar form.search button,
#luxtools__topbar form.search input[type="submit"] {
display: none;
}
#luxtools__topbar .luxtools__menus {
margin: 0;
padding: 0;
list-style: none;
display: flex;
align-items: center;
gap: 10px;
}
/* Be resilient against generic "nav ul li { display:block }" rules */
#luxtools__topbar ul,
#luxtools__topbar li {
list-style: none;
}
#luxtools__topbar .luxtools__menus > li {
display: inline-block !important;
}
/* Keep dropdown menu vertical */
#luxtools__topbar .tui-dropdown-content ul {
display: block;
}
#luxtools__topbar .tui-dropdown-content ul li {
display: block !important;
}
#luxtools__topbar .luxtools__menu {
user-select: none;
}
/* (trace styling moved above) */
#luxtools__topbar .luxtools__dropdown-title {
margin: 6px;
}
/* --- Fieldsets around sidebar and page --- */
.luxtools__sidebar-fieldset,
.luxtools__page-fieldset {
margin: 0;
}
.luxtools__page-fieldset {
margin-bottom: 0;
}
/* Avoid double spacing from DokuWiki pads */
#dokuwiki__content > .pad {
padding-top: 0;
}
/* --- Status bar --- */
#dokuwiki__pagetools {
border: none;
background-color: rgb(168, 168, 168);
}
#dokuwiki__pagetools ul {
margin: 0;
padding: 0;
list-style: none;
display: flex;
align-items: center;
flex-wrap: wrap;
}
#dokuwiki__pagetools ul li {
display: inline-flex !important;
margin: 0 0 0 10px;
padding: 2px 3px;
}
#dokuwiki__pagetools ul li a {
color: black;
text-decoration: none;
border-bottom: none;
}
#dokuwiki__pagetools ul li:active,
#dokuwiki__pagetools ul li:hover {
background-color: rgb(0, 0, 168);
}
#dokuwiki__pagetools ul li:active a,
#dokuwiki__pagetools ul li:hover a {
color: white;
}
.luxtools__hotkey {
margin-right: 4px;
}

140
main.php
View File

@@ -20,13 +20,78 @@ $sidebarElement = tpl_getConf('sidebarIsNav') ? 'nav' : 'aside';
<meta charset="UTF-8" />
<title><?php tpl_pagetitle() ?> [<?php echo strip_tags($conf['title']) ?>]</title>
<script>(function(H){H.className=H.className.replace(/\bno-js\b/,'js')})(document.documentElement)</script>
<link rel="stylesheet" href="<?php echo tpl_basedir(); ?>_vendor/tuicss/dist/tuicss.min.css" />
<script src="<?php echo tpl_basedir(); ?>_vendor/tuicss/dist/tuicss.min.js"></script>
<?php tpl_metaheaders() ?>
<meta name="viewport" content="width=device-width,initial-scale=1" />
<?php echo tpl_favicon(array('favicon', 'mobile')) ?>
<?php tpl_includeFile('meta.html') ?>
</head>
<body>
<body class="luxtools-tv tui-bg-blue-black">
<nav id="luxtools__topbar" class="tui-nav" aria-label="TurboVision top bar">
<div class="luxtools__topbar-inner">
<div class="luxtools__brand">
<?php
$logoUrl = '';
if (function_exists('tpl_getMediaFile')) {
$logoUrl = tpl_getMediaFile(array(':wiki:logo.png', 'logo.png'), false);
}
if (!$logoUrl) {
$logoUrl = ml('logo.png');
}
$brand = '<img class="luxtools__logo" src="'.hsc($logoUrl).'" alt="'.hsc($conf['title']).'" />';
$brand .= '<span class="luxtools__title">'.hsc($conf['title']).'</span>';
tpl_link(wl(), $brand, 'accesskey="h" title="[H]"');
?>
</div>
<div class="luxtools__trace" aria-label="Trace">
<?php if ($conf['breadcrumbs']) { tpl_breadcrumbs(); } ?>
<?php if ($conf['youarehere']) { tpl_youarehere(); } ?>
</div>
<ul class="luxtools__menus">
<li class="tui-dropdown luxtools__menu">
<span class="red-168-text">M</span>enu
<div class="tui-dropdown-content">
<ul>
<li class="luxtools__dropdown-title"><strong><?php echo $lang['site_tools'] ?></strong></li>
<?php
if (file_exists(DOKU_INC . 'inc/Menu/SiteMenu.php')) {
echo (new \dokuwiki\Menu\SiteMenu())->getListItems('action ', false);
} else {
_tpl_sitetools();
}
?>
<?php if ($conf['useacl'] && $showTools): ?>
<div class="tui-black-divider"></div>
<li class="luxtools__dropdown-title"><strong><?php echo $lang['user_tools'] ?></strong></li>
<?php
if (!empty($_SERVER['REMOTE_USER'])) {
echo '<li class="user">';
tpl_userinfo();
echo '</li>';
}
if (file_exists(DOKU_INC . 'inc/Menu/UserMenu.php')) {
echo (new \dokuwiki\Menu\UserMenu())->getListItems('action ', false);
} else {
_tpl_usertools();
}
?>
<?php endif ?>
</ul>
</div>
</li>
</ul>
<div class="luxtools__search">
<?php tpl_searchform() ?>
</div>
</div>
</nav>
<?php /* the "dokuwiki__top" id is needed somewhere at the top, because that's where the "back to top" button/link links to */ ?>
<?php /* tpl_classes() provides useful CSS classes; if you choose not to use it, the 'dokuwiki' class at least
should always be in one of the surrounding elements (e.g. plugins and templates depend on it) */ ?>
@@ -37,74 +102,9 @@ $sidebarElement = tpl_getConf('sidebarIsNav') ? 'nav' : 'aside';
<header id="dokuwiki__header"><div class="pad">
<?php tpl_includeFile('header.html') ?>
<div class="headings">
<h1><?php tpl_link(wl(),$conf['title'],'accesskey="h" title="[H]"') ?></h1>
<?php /* how to insert logo instead (if no CSS image replacement technique is used):
upload your logo into the data/media folder (root of the media manager) and replace 'logo.png' accordingly:
tpl_link(wl(),'<img src="'.ml('logo.png').'" alt="'.$conf['title'].'" />','id="dokuwiki__top" accesskey="h" title="[H]"') */ ?>
<?php if ($conf['tagline']): ?>
<p class="claim"><?php echo $conf['tagline'] ?></p>
<?php endif ?>
<ul class="a11y skip">
<li><a href="#dokuwiki__content"><?php echo $lang['skip_to_content'] ?></a></li>
</ul>
<div class="clearer"></div>
</div>
<div class="tools">
<!-- USER TOOLS -->
<?php if ($conf['useacl'] && $showTools): ?>
<nav id="dokuwiki__usertools" aria-labelledby="dokuwiki__usertools_heading">
<h3 class="a11y" id="dokuwiki__usertools_heading"><?php echo $lang['user_tools'] ?></h3>
<ul>
<?php if (!empty($_SERVER['REMOTE_USER'])) {
echo '<li class="user">';
tpl_userinfo(); /* 'Logged in as ...' */
echo '</li>';
} ?>
<?php if (file_exists(DOKU_INC . 'inc/Menu/UserMenu.php')) {
/* the first parameter is for an additional class, the second for if SVGs should be added */
echo (new \dokuwiki\Menu\UserMenu())->getListItems('action ', false);
} else {
/* tool menu before Greebo */
_tpl_usertools();
} ?>
</ul>
</nav>
<?php endif ?>
<!-- SITE TOOLS -->
<nav id="dokuwiki__sitetools" aria-labelledby="dokuwiki__sitetools_heading">
<h3 class="a11y" id="dokuwiki__sitetools_heading"><?php echo $lang['site_tools'] ?></h3>
<?php tpl_searchform() ?>
<?php
// mobile menu (combines all menus in one dropdown)
// if (file_exists(DOKU_INC . 'inc/Menu/MobileMenu.php')) {
// echo (new \dokuwiki\Menu\MobileMenu())->getDropdown($lang['tools']);
// } else {
// tpl_actiondropdown($lang['tools']);
// }
?>
<ul>
<?php if (file_exists(DOKU_INC . 'inc/Menu/SiteMenu.php')) {
echo (new \dokuwiki\Menu\SiteMenu())->getListItems('action ', false);
} else {
_tpl_sitetools();
} ?>
</ul>
</nav>
</div>
<div class="clearer"></div>
<!-- BREADCRUMBS -->
<?php if($conf['breadcrumbs']){ ?>
<div class="breadcrumbs"><?php tpl_breadcrumbs() ?></div>
<?php } ?>
<?php if($conf['youarehere']){ ?>
<div class="breadcrumbs"><?php tpl_youarehere() ?></div>
<?php } ?>
<div class="clearer"></div>
<hr class="a11y" />
@@ -116,9 +116,12 @@ $sidebarElement = tpl_getConf('sidebarIsNav') ? 'nav' : 'aside';
<!-- ********** ASIDE ********** -->
<?php if ($showSidebar): ?>
<<?php echo $sidebarElement ?> id="dokuwiki__aside" aria-label="<?php echo $lang['sidebar'] ?>"><div class="pad aside include group">
<fieldset class="tui-fieldset luxtools__sidebar-fieldset">
<legend><?php echo $lang['sidebar'] ?></legend>
<?php tpl_includeFile('sidebarheader.html') ?>
<?php tpl_include_page($conf['sidebar'], 1, 1) /* includes the nearest sidebar page */ ?>
<?php tpl_includeFile('sidebarfooter.html') ?>
</fieldset>
<div class="clearer"></div>
</div></<?php echo $sidebarElement ?>><!-- /aside -->
<?php endif; ?>
@@ -130,7 +133,10 @@ $sidebarElement = tpl_getConf('sidebarIsNav') ? 'nav' : 'aside';
<div class="page">
<!-- wikipage start -->
<fieldset class="tui-fieldset luxtools__page-fieldset">
<legend class="center"><?php echo hsc($ID); ?></legend>
<?php tpl_content() /* the main content */ ?>
</fieldset>
<!-- wikipage stop -->
<div class="clearer"></div>
</div>
@@ -144,7 +150,7 @@ $sidebarElement = tpl_getConf('sidebarIsNav') ? 'nav' : 'aside';
<!-- PAGE ACTIONS -->
<?php if ($showTools): ?>
<nav id="dokuwiki__pagetools" aria-labelledby="dokuwiki__pagetools_heading">
<nav id="dokuwiki__pagetools" class="tui-statusbar" aria-labelledby="dokuwiki__pagetools_heading">
<h3 class="a11y" id="dokuwiki__pagetools_heading"><?php echo $lang['page_tools'] ?></h3>
<ul>
<?php if (file_exists(DOKU_INC . 'inc/Menu/PageMenu.php')) {

View File

@@ -1 +1,49 @@
// template-related scripts go here...
(function () {
'use strict';
function extractHotkey(linkEl) {
if (!linkEl) return '';
// Prefer the human-facing "[X]" in the title when present.
// DokuWiki commonly uses titles like "Edit this page [E]".
var title = linkEl.getAttribute('title') || '';
var match = title.match(/\[([^\]]+)\]\s*$/);
if (match && match[1]) return match[1].trim();
var accessKey = linkEl.getAttribute('accesskey') || '';
if (accessKey) return accessKey.trim().toUpperCase();
return '';
}
function prependHotkey(linkEl, hotkey) {
if (!hotkey) return;
if (linkEl.querySelector('.luxtools__hotkey')) return;
var label = (linkEl.textContent || '').trim();
if (!label) return;
linkEl.textContent = '';
var span = document.createElement('span');
span.className = 'luxtools__hotkey red-168-text';
span.textContent = hotkey;
linkEl.appendChild(span);
linkEl.appendChild(document.createTextNode(' ' + label));
}
document.addEventListener('DOMContentLoaded', function () {
var pagetools = document.getElementById('dokuwiki__pagetools');
if (!pagetools) return;
var links = pagetools.querySelectorAll('a');
for (var i = 0; i < links.length; i++) {
var hotkey = extractHotkey(links[i]);
if (!hotkey) continue;
prependHotkey(links[i], hotkey);
}
});
})();

View File

@@ -43,6 +43,9 @@ css/design.css = screen
css/content.css = screen
css/includes.css = screen
; TurboVision / TuiCSS integration overrides (keep last)
css/tuivision.css = screen
css/mobile.css = all
css/print.css = print
@@ -59,32 +62,33 @@ css/print.css = print
;------ guaranteed dokuwiki color placeholders that every plugin can use
; main text and background colors
__text__ = "#333" ; @ini_text
__background__ = "#fff" ; @ini_background
; TurboVision-style dark defaults
__text__ = "#ffffff" ; @ini_text
__background__ = "#000000" ; @ini_background
; alternative text and background colors
__text_alt__ = "#999" ; @ini_text_alt
__background_alt__ = "#eee" ; @ini_background_alt
__text_alt__ = "#c0c0c0" ; @ini_text_alt
__background_alt__ = "#0000a8" ; @ini_background_alt
; neutral text and background colors
__text_neu__ = "#666" ; @ini_text_neu
__background_neu__ = "#ddd" ; @ini_background_neu
__text_neu__ = "#ffffff" ; @ini_text_neu
__background_neu__ = "#0000a8" ; @ini_background_neu
; border color
__border__ = "#ccc" ; @ini_border
__border__ = "#ffffff" ; @ini_border
; highlighted text (e.g. search snippets)
__highlight__ = "#ff9" ; @ini_highlight
__highlight__ = "#ffff00" ; @ini_highlight
; link color
__link__ = "#00c" ; @ini_link
__link__ = "#00ffff" ; @ini_link
;--------------------------------------------------------------------------
; these are used for other links
__existing__ = "#090" ; @ini_existing
__missing__ = "#f30" ; @ini_missing
__existing__ = "#00ff00" ; @ini_existing
__missing__ = "#ff5555" ; @ini_missing
; widths
__site_width__ = "64em" ; @ini_site_width
__sidebar_width__ = "16em" ; @ini_sidebar_width
; color of the web app (used by the core, not by the template)
__theme_color__ = "#eee" ; @ini_theme_color
__theme_color__ = "#0000a8" ; @ini_theme_color