static site generator part 4 --- user-selectable styles

not entirely happy about using JavaScript, but I think I figured out a
way to load the selected style via cookie without causing the page to
flash, so for the moment I'm sticking with it because I love the feature
so much

Signed-off-by: Brian S. Stephan <bss@incorporeal.org>
This commit is contained in:
Brian S. Stephan 2025-03-14 15:50:46 -05:00
parent 02c548880e
commit c9d17523ce
Signed by: bss
GPG Key ID: 3DE06D3180895FCB
3 changed files with 56 additions and 6 deletions

View File

@ -45,7 +45,9 @@ def handle_markdown_file_path(path: str) -> str:
description=get_meta_str(md, 'description'),
image=get_meta_str(md, 'image'),
content=content,
user_style=Config.PAGE_STYLES.get(Config.DEFAULT_PAGE_STYLE),
stylesheet=(Config.DEFAULT_PAGE_STYLE,
Config.PAGE_STYLES.get(Config.DEFAULT_PAGE_STYLE)),
page_styles=Config.PAGE_STYLES,
base_url=Config.BASE_HOST + instance_resource_path_to_request_path(path),
navs=parent_navs,
mtime=mtime.strftime('%Y-%m-%d %H:%M:%S %Z'),

View File

@ -45,11 +45,11 @@ def build():
tmp_output_dir = tempfile.mkdtemp(dir=os.path.dirname(output_dir))
cprint(f"creating temporary directory '{tmp_output_dir}' for writing", 'green')
# CORE CONTENT
# copy core content
pages_dir = os.path.join(instance_dir, 'pages')
copy_to_destination(pages_dir, tmp_output_dir)
# STATIC DIR
# copy the program's static dir
program_static_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'static')
static_output_dir = os.path.join(tmp_output_dir, 'static')
try:
@ -59,7 +59,7 @@ def build():
pass
copy_to_destination(program_static_dir, static_output_dir, convert_markdown=False)
# INSTANCE STATIC DIR
# copy the instance's static dir --- should I deprecate this since it could just be stuff in pages/static/?
custom_static_dir = os.path.join(instance_dir, 'custom-static')
copy_to_destination(custom_static_dir, static_output_dir, convert_markdown=False)

View File

@ -6,16 +6,64 @@ SPDX-License-Identifier: AGPL-3.0-or-later
<!doctype html>
<html lang="en">
<title>{{ title }}</title>
<meta charset="utf-8">
{% if title %}<meta property="og:title" content="{{ title }}">{% endif %}
{% if description %}<meta property="og:description" content="{{ description }}">{% endif %}
<meta property="og:url" content="{{ base_url }}">
{% if image %}<meta property="og:image" content="{{ image }}">{% endif %}
<meta name="twitter:card" content="summary_large_image">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="{{ user_style }}">
<link rel="stylesheet" type="text/css" title="{{ stylesheet.0 }}" href="{{ stylesheet.1 }}">
{% for style, stylesheet in page_styles.items() %}
<link rel="alternate stylesheet" type="text/css" title="{{ style }}" href="{{ stylesheet }}" />
{% endfor %}
<link rel="icon" href="{% if config.FAVICON %}{{ config.FAVICON }}{% else %}/static/img/favicon.png{% endif %}">
<link rel="alternate" type="application/atom+xml" href="/feed/atom">
<link rel="alternate" type="application/rss+xml" href="/feed/rss">
<script type="text/javascript">
// loathe as I am to use JavaScript, this style selection is one of my favorite parts
// of my CMS, so I want to keep it around even in the static site
function applyStyle(styleName) {
// disable all stylesheets except the one to apply, the user style
var i, link_tag;
for (i = 0, link_tag = document.getElementsByTagName("link"); i < link_tag.length; i++ ) {
// find the stylesheets with titles, meaning they can be disabled/enabled
if ((link_tag[i].rel.indexOf("stylesheet") != -1) && link_tag[i].title) {
alert(link_tag[i].title);
link_tag[i].disabled = true;
if (link_tag[i].title == styleName) {
link_tag[i].disabled = false ;
}
}
}
}
function setStyle(styleName) {
document.cookie = "user-style=" + encodeURIComponent(styleName) + "; max-age=31536000";
applyStyle(styleName);
}
function applyStyleFromCookie() {
// get the user style cookie and set that specified style as the active one
var styleName = getCookie("user-style");
alert(styleName);
if (styleName) {
applyStyle(styleName);
}
}
function getCookie(cookieName) {
// find the desired cookie from the document's cookie(s) string
let matches = document.cookie.match(new RegExp(
"(?:^|; )" + cookieName.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
));
alert(matches);
return matches ? decodeURIComponent(matches[1]) : undefined;
}
applyStyleFromCookie();
</script>
<div {% block site_class %}class="site-wrap site-wrap-normal-width"{% endblock %}>
{% block header %}
@ -29,7 +77,7 @@ SPDX-License-Identifier: AGPL-3.0-or-later
{% if page_styles %}
<div class="styles">
{% for style in page_styles %}
<a href="?style={{ style }}">[{{ style }}]</a>
<a href="#" onclick="setStyle('{{ style }}'); return false;">[{{ style }}]</a>
{% endfor %}
</div>
{% endif %}