Added module with functions for managing SASS/CSS themes of website

This commit is contained in:
Alex Tavarez
2025-09-02 17:44:55 -04:00
parent 6457abb55e
commit a27c175068

136
lib/sukaato_web/theme.ex Normal file
View File

@@ -0,0 +1,136 @@
defmodule SukaatoWeb.Theme do
@moduledoc """
Manage website themes.
"""
@rel_proj_root "../.."
@central_sass "export.sass"
@site_config Toml.decode_file(Path.expand(@rel_proj_root <> "/site.toml", __DIR__))
@theme_filepath Path.expand(@rel_proj_root <> "/assets/sass/themes/" <> elem(@site_config, 1)["site"]["theme"] <> "/" <> @central_sass, __DIR__)
@theme_glob Path.expand(@rel_proj_root <> "/assets/sass/themes/*/" <> @central_sass, __DIR__)
@theme_linkpath Path.expand(@rel_proj_root <> "/assets/sass/app.sass", __DIR__)
defp get_installed() do
path_list = Path.wildcard(@theme_glob)
extract_theme = fn theme_path -> Enum.at(Path.split(theme_path), length(Path.split(theme_path)) - 2) end
installed = Enum.map(path_list, fn p -> extract_theme.(p) end)
installed
end
@doc """
List installed website themes.
"""
def list() do
get_installed()
end
defp get_current() do
if File.exists?(@theme_linkpath) do
link_path = File.read_link(@theme_linkpath)
if elem(link_path, 0) == :ok do
split_path = Path.split(elem(link_path, 1))
current_theme = Enum.at(split_path, length(split_path) - 2)
{:ok, current_theme}
else
{:error, "link not traceable--sure its a link?"}
end
else
{:error, "symbolic link does not exist"}
end
end
@doc """
List website themes under project root's 'assets/sass/themes' path.
"""
def list(status) do
case status do
:installed ->
get_installed()
:current ->
elem(get_current(), 1)
end
end
defp change_theme_path(theme_name) do
Path.expand(@rel_proj_root <> "/assets/sass/themes/" <> theme_name <> "/" <> @central_sass, __DIR__)
end
@doc """
Update website theme based on stored website settings, refreshes current theme otherwise.
"""
def update() do
if File.exists?(@theme_filepath) do
result = File.ln_s(@theme_filepath, @theme_linkpath)
if result == :ok do
{:ok, @theme_linkpath}
else
{:error, {@theme_filepath, @theme_linkpath}}
end
else
link_path = File.read_link(@theme_linkpath)
if Enum.at(link_path, 0) == :ok do
split_path = Path.split(Enum.at(link_path, 1))
current_theme = Enum.at(split_path, length(split_path) - 2)
# @TODO find some way to notify theme could not be found
current_path = change_theme_path(current_theme)
result = File.ln_s(current_path, @theme_linkpath)
if result == :ok do
{:ok, "current theme '" <> current_theme <> "' reinstated as no declared theme"}
else
result = File.ln_s(change_theme_path("default"), @theme_linkpath)
if result == :ok do
{:ok, "current theme '" <> current_theme <> "' unavailable, successful fallback to default theme"}
else
{:error, "current theme '" <> current_theme <> "' unavailable, failed fallback to default theme"}
end
end
else
{:error, @theme_linkpath}
end
end
end
@doc """
Update website theme in-memory, independent of stored website settings.
"""
def update(theme_name) do
theme_path = change_theme_path(theme_name)
if File.exists?(theme_path) do
# @TODO find some way to notify theme could not be found
result = File.ln_s(theme_path, @theme_linkpath)
if result == :ok do
{:ok, @theme_linkpath}
else
update()
end
else
update()
end
end
def grab(), do: nil
def unpack(), do: nil
def install(), do: nil
def remove(theme_name) do
theme_path = change_theme_path(theme_name)
if theme_name != "default" do
result = File.rm_rf(theme_path)
result
else
{:error, theme_name <> " cannot be uninstalled"}
end
end
end