Added themeing options

Added THEME_COLOR, THEME_COLOR_AUTO_DETECT_BROWSER_PREFERENCE, and THEME_COLOR_ENABLE_USER_OVERRIDE options
This commit is contained in:
Sumner Evans 2020-04-15 16:55:28 -06:00
parent 9b3495da5d
commit 904484e2b4
No known key found for this signature in database
GPG key ID: 8904527AB50022FD
4 changed files with 239 additions and 147 deletions

View file

@ -4,7 +4,10 @@ var gulp = require('gulp'),
minify = require('gulp-cssnano'); minify = require('gulp-cssnano');
gulp.task('less', function () { gulp.task('less', function () {
return gulp.src('./static/stylesheet/style.less') return gulp.src([
'./static/stylesheet/style.less',
'./static/stylesheet/dark-theme.less',
])
.pipe(less()) .pipe(less())
.pipe(minify()) .pipe(minify())
.pipe(rename({ .pipe(rename({

View file

@ -1,114 +1,144 @@
// This stylesheet contains style overrides for the dark theme. //
// Dark Theme CSS.
//
// If you want to always use the dark theme, then you can use a <link> like the
// following:
//
// <link rel="stylesheet" type="text/css"
// href="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/stylesheet/dark-theme-detect-preferences.min.css">
//
// If you want to enable only when the prefers-color-scheme is set to dark (and
// potentially no-preference), make sure that you add the appropriate media
// query to the <link>. For example:
//
// <link media="(prefers-color-scheme: dark), (prefers-color-scheme: no-preference)"
// rel="stylesheet"
// type="text/css"
// href="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/stylesheet/dark-theme-detect-preferences.min.css">
//
// or
//
// <link media="(prefers-color-scheme: dark)"
// rel="stylesheet"
// type="text/css"
// href="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/stylesheet/dark-theme-detect-preferences.min.css">
//
// depending on whether you want to default to dark mode or not when the user
// hasn't set a preference.
//
@import "variables.less"; @import "variables.less";
body { html:not(.light-theme), html.dark-theme {
background-color: @body-bg-dark-theme; body {
color: @text-color-dark-theme; background-color: @body-bg-dark-theme;
} color: @text-color-dark-theme;
hr {
color: @solid-dark-grey;
background-color: @solid-dark-grey;
}
aside {
background-color: @sidebar-bg-dark-theme;
color: @sidebar-text-color;
}
main {
nav {
border-bottom-color: @nav-border-color-dark-theme;
} }
nav, .translations { hr {
a { color: @solid-dark-grey;
border-color: @nav-border-color-dark-theme; background-color: @solid-dark-grey;
}
aside {
background-color: @sidebar-bg-dark-theme;
color: @sidebar-text-color;
}
main {
nav {
border-bottom-color: @nav-border-color-dark-theme;
}
nav, .translations {
a {
border-color: @nav-border-color-dark-theme;
}
}
article {
kbd {
background-color: #080808;
color: @light-grey;
}
*:not(pre) > code {
background-color: #080808;
border-color: #000;
}
}
footer {
border-top-color: @footer-border-color-dark-theme;
} }
} }
article { div.related-posts {
kbd { border-color: @rel-post-border-color-dark-theme;
background-color: #080808; }
color: @light-grey;
}
*:not(pre) > code { // Admonition
background-color: #080808; div.admonition.attention {
border-color: #000; p, div {
color: @admonition-attention-color-dark-theme;
background-color: @admonition-attention-bg-color-dark-theme;
} }
} }
footer { div.admonition.caution {
border-top-color: @footer-border-color-dark-theme; p, div {
} color: @admonition-caution-color-dark-theme;
} background-color: @admonition-caution-bg-color-dark-theme;
}
div.related-posts { }
border-color: @rel-post-border-color-dark-theme;
} div.admonition.danger {
p, div {
// Admonition color: @admonition-danger-color-dark-theme;
div.admonition.attention { background-color: @admonition-danger-bg-color-dark-theme;
p, div { }
color: @admonition-attention-color-dark-theme; }
background-color: @admonition-attention-bg-color-dark-theme;
} div.admonition.error {
} p, div {
color: @admonition-error-color-dark-theme;
div.admonition.caution { background-color: @admonition-error-bg-color-dark-theme;
p, div { }
color: @admonition-caution-color-dark-theme; }
background-color: @admonition-caution-bg-color-dark-theme;
} div.admonition.hint {
} p, div {
color: @admonition-hint-color-dark-theme;
div.admonition.danger { background-color: @admonition-hint-bg-color-dark-theme;
p, div { }
color: @admonition-danger-color-dark-theme; }
background-color: @admonition-danger-bg-color-dark-theme;
} div.admonition.important {
} p, div {
color: @admonition-important-color-dark-theme;
div.admonition.error { background-color: @admonition-important-bg-color-dark-theme;
p, div { }
color: @admonition-error-color-dark-theme; }
background-color: @admonition-error-bg-color-dark-theme;
} div.admonition.note {
} p, div {
color: @admonition-note-color-dark-theme;
div.admonition.hint { background-color: @admonition-note-bg-color-dark-theme;
p, div { }
color: @admonition-hint-color-dark-theme; }
background-color: @admonition-hint-bg-color-dark-theme;
} div.admonition.tip {
} p, div {
color: @admonition-tip-color-dark-theme;
div.admonition.important { background-color: @admonition-tip-bg-color-dark-theme;
p, div { }
color: @admonition-important-color-dark-theme; }
background-color: @admonition-important-bg-color-dark-theme;
} div.admonition.warning {
} p, div {
color: @admonition-warning-color-dark-theme;
div.admonition.note { background-color: @admonition-warning-bg-color-dark-theme;
p, div { }
color: @admonition-note-color-dark-theme;
background-color: @admonition-note-bg-color-dark-theme;
}
}
div.admonition.tip {
p, div {
color: @admonition-tip-color-dark-theme;
background-color: @admonition-tip-bg-color-dark-theme;
}
}
div.admonition.warning {
p, div {
color: @admonition-warning-color-dark-theme;
background-color: @admonition-warning-bg-color-dark-theme;
} }
} }

View file

@ -5,7 +5,11 @@
{% endif %} {% endif %}
<!DOCTYPE html> <!DOCTYPE html>
<html lang="{{ DEFAULT_LANG }}"> <html lang="{{ DEFAULT_LANG }}"
{% if not THEME_COLOR_AUTO_DETECT_BROWSER_PREFERENCE %}
class="{{ THEME_COLOR|default('light') }}-theme"
{% endif %}
>
<head> <head>
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" />
@ -28,6 +32,50 @@
<link rel="stylesheet" type="text/css" href="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/stylesheet/style.min.css"> <link rel="stylesheet" type="text/css" href="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/stylesheet/style.min.css">
{% endif %} {% endif %}
<!--
DARK THEME STYLES
The dark theme will be enabled if any of the following are true:
* the <html> tag has the .dark-theme class.
* THEME_COLOR_AUTO_DETECT_BROWSER_PREFERENCE is true and the appropriate color scheme preference
is set in the browser and the <html> tag does not have the .light-theme class.
-->
<link rel="stylesheet" type="text/css"
{% if THEME_COLOR_AUTO_DETECT_BROWSER_PREFERENCE %}
{% if THEME_COLOR|default("light") == "dark" %}
media="(prefers-color-scheme: dark), (prefers-color-scheme: no-preference)"
{% else %}
media="(prefers-color-scheme: dark)"
{% endif %}
{% endif %}
href="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/stylesheet/dark-theme.min.css">
<!--
PYGMENTS STYLES
-->
{% if THEME_COLOR_AUTO_DETECT_BROWSER_PREFERENCE or THEME_COLOR == "dark" %}
<link rel="stylesheet" type="text/css"
{% if THEME_COLOR_AUTO_DETECT_BROWSER_PREFERENCE %}
{% if THEME_COLOR|default("light") == "dark" %}
media="(prefers-color-scheme: dark), (prefers-color-scheme: no-preference)"
{% else %}
media="(prefers-color-scheme: dark)"
{% endif %}
{% endif %}
href="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/pygments/{{ PYGMENTS_STYLE_DARK or PYGMENTS_STYLE or 'monokai' }}.min.css">
{% endif %}
{% if THEME_COLOR_AUTO_DETECT_BROWSER_PREFERENCE or not THEME_COLOR or THEME_COLOR == "light" %}
<link rel="stylesheet" type="text/css"
{% if THEME_COLOR_AUTO_DETECT_BROWSER_PREFERENCE %}
{% if THEME_COLOR|default("light") == "dark" %}
media="(prefers-color-scheme: light)"
{% else %}
media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)"
{% endif %}
{% endif %}
href="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/pygments/{{ PYGMENTS_STYLE|default('github') }}.min.css">
{% endif %}
{% if USE_TIPUE_SEARCH %} {% if USE_TIPUE_SEARCH %}
<script src="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/tipuesearch/jquery.min.js"></script> <script src="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/tipuesearch/jquery.min.js"></script>
<script src="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/tipuesearch/tipuesearch.min.js"></script> <script src="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/tipuesearch/tipuesearch.min.js"></script>
@ -36,12 +84,6 @@
<link rel="stylesheet" href="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/tipuesearch/tipuesearch.min.css" /> <link rel="stylesheet" href="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/tipuesearch/tipuesearch.min.css" />
{% endif %} {% endif %}
<link rel="stylesheet" type="text/css"
media="(prefers-color-scheme: dark)"
href="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/pygments/{{ PYGMENTS_STYLE_DARK|default('monokai') }}.min.css">
<link rel="stylesheet" type="text/css"
media="(prefers-color-scheme: light), (prefers-color-scheme: no-preference)"
href="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/pygments/{{ PYGMENTS_STYLE|default('github') }}.min.css">
<link rel="stylesheet" type="text/css" href="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/font-awesome/css/fontawesome.css"> <link rel="stylesheet" type="text/css" href="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/font-awesome/css/fontawesome.css">
<link rel="stylesheet" type="text/css" href="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/font-awesome/css/brands.css"> <link rel="stylesheet" type="text/css" href="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/font-awesome/css/brands.css">
<link rel="stylesheet" type="text/css" href="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/font-awesome/css/solid.css"> <link rel="stylesheet" type="text/css" href="{{ SITEURL }}/{{ THEME_STATIC_DIR }}/font-awesome/css/solid.css">

View file

@ -1,53 +1,70 @@
<p>{{ _('Built with %(pelican_url)s using %(flex_url)s theme', <p>
pelican_url='<a href="http://getpelican.com" target="_blank">Pelican</a>', {{
flex_url='<a href="http://bit.ly/flex-pelican" target="_blank">Flex</a>'|safe) }} _('Built with %(pelican_url)s using %(flex_url)s theme',
pelican_url='<a href="http://getpelican.com" target="_blank">Pelican</a>',
flex_url='<a href="http://bit.ly/flex-pelican" target="_blank">Flex</a>'|safe)
}}
{% if THEME_COLOR_ENABLE_USER_OVERRIDE %}
<span class="footer-separator">|</span> <span class="footer-separator">|</span>
Switch to the Switch to the
<a href="javascript:void(0)" onclick="switchTheme('dark')"> <a href="javascript:void(0)" onclick="switchTheme('dark')">
dark dark
</a>|<a href="javascript:void(0)" onclick="switchTheme('light')"> </a>|<a href="javascript:void(0)" onclick="switchTheme('light')">
light light
</a>|<a href="javascript:void(0)" onclick="switchTheme('browser')">
browser
</a> </a>
{% if THEME_COLOR_AUTO_DETECT_BROWSER_PREFERENCE %}
|<a href="javascript:void(0)" onclick="switchTheme('browser')">
browser
</a>
{% endif %}
theme theme
{% endif %}
</p> </p>
<script> {% if THEME_COLOR_ENABLE_USER_OVERRIDE %}
const darkSchemeWatch = window.matchMedia('(prefers-color-scheme: dark)'); <script>
{% if THEME_COLOR_AUTO_DETECT_BROWSER_PREFERENCE %}
const darkSchemeWatch = window.matchMedia('(prefers-color-scheme: dark)');
{% endif %}
function detectThemeAndSwitchStyle() { function detectThemeAndSwitchStyle() {
let theme = localStorage.getItem('themeOverride'); let theme = localStorage.getItem('themeOverride');
if (theme !== 'light' && theme !== 'dark') { if (theme !== 'light' && theme !== 'dark') {
theme = darkSchemeWatch.matches ? 'dark' : 'light'; {% if THEME_COLOR_AUTO_DETECT_BROWSER_PREFERENCE %}
} theme = darkSchemeWatch.matches ? 'dark' : 'light';
console.log(`Switching theme to ${theme}.`) {% else %}
theme = '{{ THEME_COLOR|default("light") }}';
// Find the pygments CSS files (there are two, one for each theme) and {% endif %}
// change them both to the theme specified by the user.
const pygmentsTheme = theme === 'light'
? '{{ PYGMENTS_STYLE|default('github') }}'
: '{{ PYGMENTS_STYLE_DARK|default('monokai') }}'
Array.from(document.head.getElementsByTagName('link')).forEach(linkEl => {
if (linkEl.href.match(/\/theme\/pygments\/.*\.min\.css/)) {
linkEl.href = `/theme/pygments/${pygmentsTheme}.min.css`;
} }
});
const htmlElement = document.getElementsByTagName('html')[0]; // Find the pygments CSS files (there are two, one for each theme) and
if (theme === 'dark') { // change them both to the theme specified by the user.
htmlElement.classList.add('dark-theme'); const pygmentsTheme = theme === 'light'
htmlElement.classList.remove('light-theme'); ? '{{ PYGMENTS_STYLE|default('github') }}'
} else { : '{{ PYGMENTS_STYLE_DARK or PYGMENTS_STYLE or 'monokai' }}';
htmlElement.classList.add('light-theme'); Array.from(document.head.getElementsByTagName('link')).forEach(linkEl => {
htmlElement.classList.remove('dark-theme'); if (linkEl.href.match(/\/theme\/pygments\/.*\.min\.css/)) {
linkEl.href = `/theme/pygments/${pygmentsTheme}.min.css`;
}
});
const htmlElement = document.getElementsByTagName('html')[0];
if (theme === 'dark') {
htmlElement.classList.add('dark-theme');
htmlElement.classList.remove('light-theme');
} else {
htmlElement.classList.add('light-theme');
htmlElement.classList.remove('dark-theme');
}
}
function switchTheme(themeOverride) {
localStorage.setItem('themeOverride', themeOverride);
detectThemeAndSwitchStyle();
} }
}
function switchTheme(themeOverride) {
localStorage.setItem('themeOverride', themeOverride);
detectThemeAndSwitchStyle(); detectThemeAndSwitchStyle();
} {% if THEME_COLOR_AUTO_DETECT_BROWSER_PREFERENCE %}
darkSchemeWatch.addListener(detectThemeAndSwitchStyle);
detectThemeAndSwitchStyle(); {% endif %}
darkSchemeWatch.addListener(detectThemeAndSwitchStyle); </script>
</script> {% endif %}