luci-theme-bootstrap: translate Lua templates to ucode equivalents
authorJo-Philipp Wich <jo@mein.io>
Fri, 9 Sep 2022 18:08:57 +0000 (20:08 +0200)
committerJo-Philipp Wich <jo@mein.io>
Mon, 24 Oct 2022 23:03:37 +0000 (01:03 +0200)
Add ucode template equivalents for the Lua templates used by the theme.

Signed-off-by: Jo-Philipp Wich <jo@mein.io>
themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap-dark [deleted symlink]
themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap-light [deleted symlink]
themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap/footer.htm [deleted file]
themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap/header.htm [deleted file]
themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap/sysauth.htm [deleted file]
themes/luci-theme-bootstrap/ucode/template/themes/bootstrap-dark [new symlink]
themes/luci-theme-bootstrap/ucode/template/themes/bootstrap-light [new symlink]
themes/luci-theme-bootstrap/ucode/template/themes/bootstrap/footer.ut [new file with mode: 0644]
themes/luci-theme-bootstrap/ucode/template/themes/bootstrap/header.ut [new file with mode: 0644]
themes/luci-theme-bootstrap/ucode/template/themes/bootstrap/sysauth.ut [new file with mode: 0644]

diff --git a/themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap-dark b/themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap-dark
deleted file mode 120000 (symlink)
index ac7bcbb..0000000
+++ /dev/null
@@ -1 +0,0 @@
-bootstrap
\ No newline at end of file
diff --git a/themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap-light b/themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap-light
deleted file mode 120000 (symlink)
index ac7bcbb..0000000
+++ /dev/null
@@ -1 +0,0 @@
-bootstrap
\ No newline at end of file
diff --git a/themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap/footer.htm b/themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap/footer.htm
deleted file mode 100644 (file)
index 48d9b98..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-<%#
-       Copyright 2008 Steven Barth <steven@midlink.org>
-       Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
-       Copyright 2012 David Menting <david@nut-bolt.nl>
-       Licensed to the public under the Apache License 2.0.
--%>
-
-               <% if not blank_page then %>
-               <%   local ver = require "luci.version" %>
-               </div>
-               <footer>
-                       <span>
-                               <a href="https://github.com/openwrt/luci">Powered by <%= ver.luciname %> (<%= ver.luciversion %>)</a> / <%= ver.distversion %>
-                       </span>
-                       <ul class="breadcrumb pull-right" id="modemenu" style="display:none"></ul>
-               </footer>
-               <script type="text/javascript">L.require('menu-bootstrap')</script>
-               <% end %>
-       </body>
-</html>
-
diff --git a/themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap/header.htm b/themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap/header.htm
deleted file mode 100644 (file)
index 37d18a2..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-<%#
- Copyright 2008 Steven Barth <steven@midlink.org>
- Copyright 2008-2016 Jo-Philipp Wich <jow@openwrt.org>
- Copyright 2012 David Menting <david@nut-bolt.nl>
- Licensed to the public under the Apache License 2.0.
--%>
-
-<%
-       local sys  = require "luci.sys"
-       local util = require "luci.util"
-       local http = require "luci.http"
-       local disp = require "luci.dispatcher"
-
-       local boardinfo = util.ubus("system", "board")
-
-       local node = disp.context.dispatched
-
-       local darkpref
-
-       if theme == "bootstrap-dark" then
-               darkpref = "true"
-       elseif theme == "bootstrap-light" then
-               darkpref = "false"
-       end
-
-       -- send as HTML5
-       http.prepare_content("text/html")
--%>
-<!DOCTYPE html>
-<html lang="<%=luci.i18n.context.lang%>"<%= ifattr(darkpref ~= nil, "data-darkmode", darkpref) %>>
-       <head>
-               <meta charset="utf-8">
-               <title><%=striptags( (boardinfo.hostname or "?") .. ( (node and node.title) and ' - ' .. translate(node.title) or '')) %> - LuCI</title>
-               <% if darkpref == nil then %>
-                       <script type="text/javascript">
-                               var mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'),
-                                   rootElement = document.querySelector(':root'),
-                                   setDarkMode = function(match) { rootElement.setAttribute('data-darkmode', match.matches) };
-
-                               mediaQuery.addEventListener('change', setDarkMode);
-                               setDarkMode(mediaQuery);
-                       </script>
-               <% end %>
-               <meta name="viewport" content="initial-scale=1.0">
-               <link rel="stylesheet" href="<%=media%>/cascade.css">
-               <link rel="stylesheet" media="only screen and (max-device-width: 854px)" href="<%=media%>/mobile.css" type="text/css" />
-               <link rel="shortcut icon" href="<%=media%>/favicon.png">
-               <% if node and node.css then %>
-                       <link rel="stylesheet" href="<%=resource%>/<%=node.css%>">
-               <% end -%>
-               <% if css then %>
-                       <style title="text/css"><%= css %></style>
-               <% end -%>
-               <script src="<%=url('admin/translations', luci.i18n.context.lang)%><%# ?v=PKG_VERSION %>"></script>
-               <script src="<%=resource%>/cbi.js"></script>
-       </head>
-
-       <body class="lang_<%=luci.i18n.context.lang%> <% if node then %><%= striptags( node.title ) %><%- end %>" data-page="<%= pcdata(table.concat(disp.context.requestpath, "-")) %>">
-               <% if not blank_page then %>
-               <header>
-                       <a class="brand" href="/"><%=striptags(boardinfo.hostname or "?")%></a>
-                       <ul class="nav" id="topmenu" style="display:none"></ul>
-                       <div id="indicators" class="pull-right"></div>
-               </header>
-
-               <div id="maincontent" class="container">
-                       <%- if luci.sys.process.info("uid") == 0 and luci.sys.user.getuser("root") and not luci.sys.user.getpasswd("root") then -%>
-                               <div class="alert-message warning">
-                                       <h4><%:No password set!%></h4>
-                                       <p><%:There is no password set on this router. Please configure a root password to protect the web interface.%></p>
-                                       <% if disp.lookup("admin/system/admin") then %>
-                                         <div class="right"><a class="btn" href="<%=url("admin/system/admin")%>"><%:Go to password configuration...%></a></div>
-                                       <% end %>
-                               </div>
-                       <%- end -%>
-
-                       <%- if boardinfo.rootfs_type == "initramfs" then -%>
-                               <div class="alert-message warning">
-                                       <h4><%:System running in recovery (initramfs) mode.%></h4>
-                                       <p><%:No changes to settings will be stored and are lost after rebooting. This mode should only be used to install a firmware upgrade%></p>
-                                       <% if disp.lookup("admin/system/flash") then %>
-                                         <div class="right"><a class="btn" href="<%=url("admin/system/flash")%>"><%:Go to firmware upgrade...%></a></div>
-                                       <% end %>
-                               </div>
-                       <%- end -%>
-
-                       <noscript>
-                               <div class="alert-message warning">
-                                       <h4><%:JavaScript required!%></h4>
-                                       <p><%:You must enable JavaScript in your browser or LuCI will not work properly.%></p>
-                               </div>
-                       </noscript>
-
-                       <div id="tabmenu" style="display:none"></div>
-               <% end %>
diff --git a/themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap/sysauth.htm b/themes/luci-theme-bootstrap/luasrc/view/themes/bootstrap/sysauth.htm
deleted file mode 100644 (file)
index 72b0478..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-<%#
- Copyright 2021 Jo-Philipp Wich <jo@mein.io>
- Licensed to the public under the Apache License 2.0.
--%>
-
-<%
-       -- tell bootstrap's templates to not render header and footer
-       blank_page = true
-%>
-
-<%+header%>
-
-<section hidden>
-       <form method="post" class="cbi-map">
-               <div class="cbi-section">
-                       <div class="cbi-section-node">
-                               <div class="cbi-value">
-                                       <label class="cbi-value-title" for="luci_username"><%:Username%></label>
-                                       <div class="cbi-value-field">
-                                               <input name="luci_username" id="luci_username" type="text" autocomplete="username" <%=attr("value", duser)%>>
-                                       </div>
-                               </div>
-                               <div class="cbi-value">
-                                       <label class="cbi-value-title" for="luci_password"><%:Password%></label>
-                                       <div class="cbi-value-field">
-                                               <input name="luci_password" id="luci_password" type="password" autocomplete="current-password">
-                                       </div>
-                               </div>
-                       </div>
-               </div>
-       </form>
-
-       <hr>
-
-       <% if fuser then %>
-       <div class="alert-message error">
-               <%:Invalid username and/or password! Please try again.%>
-       </div>
-       <% end %>
-
-       <button class="btn cbi-button-positive important"><%:Login%></button>
-</section>
-
-<div id="view">
-       <div class="spinning"><%:Loading view…%></div>
-       <script type="text/javascript">
-               L.require('ui').then(function(ui) {
-                       ui.instantiateView('bootstrap.sysauth');
-               });
-       </script>
-</div>
-
-<%+footer%>
diff --git a/themes/luci-theme-bootstrap/ucode/template/themes/bootstrap-dark b/themes/luci-theme-bootstrap/ucode/template/themes/bootstrap-dark
new file mode 120000 (symlink)
index 0000000..ac7bcbb
--- /dev/null
@@ -0,0 +1 @@
+bootstrap
\ No newline at end of file
diff --git a/themes/luci-theme-bootstrap/ucode/template/themes/bootstrap-light b/themes/luci-theme-bootstrap/ucode/template/themes/bootstrap-light
new file mode 120000 (symlink)
index 0000000..ac7bcbb
--- /dev/null
@@ -0,0 +1 @@
+bootstrap
\ No newline at end of file
diff --git a/themes/luci-theme-bootstrap/ucode/template/themes/bootstrap/footer.ut b/themes/luci-theme-bootstrap/ucode/template/themes/bootstrap/footer.ut
new file mode 100644 (file)
index 0000000..6031724
--- /dev/null
@@ -0,0 +1,20 @@
+               {% if (!blank_page): %}
+               </div>
+               <footer>
+                       <span>
+                               Powered by
+                               <a href="https://github.com/openwrt/luci">
+                                       {{ version.luciname }} ({{ version.luciversion }})</a>
+                               /
+                               <a href="{{ entityencode(version.disturl ?? '#', true) }}">
+                                       {{ version.distname }} {{ version.distversion }} ({{ version.distrevision }})</a>
+                               {% if (lua_active): %}
+                                       / {{ _('Lua compatibility mode active') }}
+                               {% endif %}
+                       </span>
+                       <ul class="breadcrumb pull-right" id="modemenu" style="display:none"></ul>
+               </footer>
+               <script type="text/javascript">L.require('menu-bootstrap')</script>
+               {% endif %}
+       </body>
+</html>
diff --git a/themes/luci-theme-bootstrap/ucode/template/themes/bootstrap/header.ut b/themes/luci-theme-bootstrap/ucode/template/themes/bootstrap/header.ut
new file mode 100644 (file)
index 0000000..b7bc770
--- /dev/null
@@ -0,0 +1,83 @@
+{#
+ Copyright 2008 Steven Barth <steven@midlink.org>
+ Copyright 2012 David Menting <david@nut-bolt.nl>
+ Copyright 2008-2022 Jo-Philipp Wich <jo@mein.io>
+ Licensed to the public under the Apache License 2.0.
+-#}
+
+{%
+       import { getuid, getspnam } from 'luci.core';
+
+       const boardinfo = ubus.call('system', 'board');
+       const darkpref = (theme == 'bootstrap-dark' ? 'true' : (theme == 'bootstrap-light' ? 'false' : null));
+
+       http.prepare_content('text/html; charset=UTF-8');
+-%}
+
+<!DOCTYPE html>
+<html lang="{{ dispatcher.lang }}" {{ darkpref ? `data-darkmode="${darkpref}"` : '' }}>
+       <head>
+               <meta charset="utf-8">
+               <title>{{ striptags(`${boardinfo.hostname ?? '?'}${node ? ` - ${node.title}` : ''}`) }} - LuCI</title>
+               {% if (!darkpref): %}
+                       <script type="text/javascript">
+                               var mediaQuery = window.matchMedia('(prefers-color-scheme: dark)'),
+                                   rootElement = document.querySelector(':root'),
+                                   setDarkMode = function(match) { rootElement.setAttribute('data-darkmode', match.matches) };
+
+                               mediaQuery.addEventListener('change', setDarkMode);
+                               setDarkMode(mediaQuery);
+                       </script>
+               {% endif %}
+               <meta name="viewport" content="initial-scale=1.0">
+               <link rel="stylesheet" href="{{ media }}/cascade.css">
+               <link rel="stylesheet" media="only screen and (max-device-width: 854px)" href="{{ media }}/mobile.css" type="text/css" />
+               <link rel="shortcut icon" href="{{ media }}/favicon.png">
+               {% if (node?.css): %}
+               <link rel="stylesheet" href="{{ resource }}/{{ node.css }}">
+               {% endif %}
+               {% if (css): %}
+               <style title="text/css">{{ css }}</style>
+               {% endif %}
+               <script src="{{ dispatcher.build_url('admin/translations', dispatcher.lang) }}"></script>
+               <script src="{{ resource }}/cbi.js"></script>
+       </head>
+
+       <body class="lang_{{ dispatcher.lang }} {{ entityencode(striptags(node?.title ?? ''), true) }}" data-page="{{ entityencode(join('-', ctx.request_path), true) }}">
+               {% if (!blank_page): %}
+               <header>
+                       <a class="brand" href="/">{{ striptags(boardinfo.hostname ?? '?') }}</a>
+                       <ul class="nav" id="topmenu" style="display:none"></ul>
+                       <div id="indicators" class="pull-right"></div>
+               </header>
+
+               <div id="maincontent" class="container">
+                       {% if (getuid() == 0 && getspnam('root')?.pwdp === ''): %}
+                               <div class="alert-message warning">
+                                       <h4>{{ _('No password set!') }}</h4>
+                                       <p>{{ _('There is no password set on this router. Please configure a root password to protect the web interface.') }}</p>
+                                       {% if (dispatcher.lookup("admin/system/admin")): %}
+                                         <div class="right"><a class="btn" href="{{ dispatcher.build_url("admin/system/admin") }}">{{ _('Go to password configuration...') }}</a></div>
+                                       {% endif %}
+                               </div>
+                       {% endif %}
+
+                       {% if (boardinfo.rootfs_type == "initramfs"): %}
+                               <div class="alert-message warning">
+                                       <h4>{{ _('System running in recovery (initramfs) mode.') }}</h4>
+                                       <p>{{ _('No changes to settings will be stored and are lost after rebooting. This mode should only be used to install a firmware upgrade') }}</p>
+                                       {% if (dispatcher.lookup("admin/system/flash")): %}
+                                         <div class="right"><a class="btn" href="{{ dispatcher.build_url("admin/system/flash") }}">{{ _('Go to firmware upgrade...') }}</a></div>
+                                       {% endif %}
+                               </div>
+                       {% endif %}
+
+                       <noscript>
+                               <div class="alert-message warning">
+                                       <h4>{{ _('JavaScript required!') }}</h4>
+                                       <p>{{ _('You must enable JavaScript in your browser or LuCI will not work properly.') }}</p>
+                               </div>
+                       </noscript>
+
+                       <div id="tabmenu" style="display:none"></div>
+               {% endif %}
diff --git a/themes/luci-theme-bootstrap/ucode/template/themes/bootstrap/sysauth.ut b/themes/luci-theme-bootstrap/ucode/template/themes/bootstrap/sysauth.ut
new file mode 100644 (file)
index 0000000..a172d95
--- /dev/null
@@ -0,0 +1,48 @@
+{#
+ Copyright 2022 Jo-Philipp Wich <jo@mein.io>
+ Licensed to the public under the Apache License 2.0.
+-#}
+
+{% include('header', { blank_page: true }) %}
+
+<section hidden>
+       <form method="post" class="cbi-map">
+               <div class="cbi-section">
+                       <div class="cbi-section-node">
+                               <div class="cbi-value">
+                                       <label class="cbi-value-title" for="luci_username">{{ _('Username') }}</label>
+                                       <div class="cbi-value-field">
+                                               <input name="luci_username" id="luci_username" type="text" autocomplete="username" value="{{ entityencode(duser, true) }}">
+                                       </div>
+                               </div>
+                               <div class="cbi-value">
+                                       <label class="cbi-value-title" for="luci_password">{{ _('Password') }}</label>
+                                       <div class="cbi-value-field">
+                                               <input name="luci_password" id="luci_password" type="password" autocomplete="current-password">
+                                       </div>
+                               </div>
+                       </div>
+               </div>
+       </form>
+
+       <hr>
+
+       {% if (fuser): %}
+       <div class="alert-message error">
+               {{ _('Invalid username and/or password! Please try again.') }}
+       </div>
+       {% endif %}
+
+       <button class="btn cbi-button-positive important">{{ _('Login') }}</button>
+</section>
+
+<div id="view">
+       <div class="spinning">{{ _('Loading view…') }}</div>
+       <script type="text/javascript">
+               L.require('ui').then(function(ui) {
+                       ui.instantiateView('bootstrap.sysauth');
+               });
+       </script>
+</div>
+
+{% include('footer', { blank_page: true }) %}