Packages

phoenix_kit

1.7.3
1.7.208 1.7.207 1.7.206 1.7.205 1.7.204 1.7.203 1.7.202 1.7.201 1.7.200 1.7.199 1.7.198 1.7.197 1.7.196 1.7.194 1.7.193 1.7.192 1.7.191 1.7.190 1.7.189 1.7.187 1.7.186 1.7.185 1.7.184 1.7.183 1.7.182 1.7.181 1.7.180 1.7.179 1.7.178 1.7.177 1.7.176 1.7.175 1.7.174 1.7.173 1.7.172 1.7.171 1.7.170 1.7.169 1.7.168 1.7.167 1.7.166 1.7.165 1.7.164 1.7.162 1.7.161 1.7.160 1.7.159 1.7.157 1.7.156 1.7.155 1.7.154 1.7.153 1.7.152 1.7.151 1.7.150 1.7.149 1.7.146 1.7.145 1.7.144 1.7.143 1.7.138 1.7.133 1.7.132 1.7.131 1.7.130 1.7.128 1.7.126 1.7.125 1.7.121 1.7.120 1.7.119 1.7.118 1.7.117 1.7.116 1.7.115 1.7.114 1.7.113 1.7.112 1.7.111 1.7.110 1.7.109 1.7.108 1.7.107 1.7.106 1.7.105 1.7.104 1.7.103 1.7.102 1.7.101 1.7.100 1.7.99 1.7.98 1.7.97 1.7.96 1.7.95 1.7.94 1.7.93 1.7.92 1.7.91 1.7.90 1.7.89 1.7.88 1.7.87 1.7.86 1.7.85 1.7.84 1.7.83 1.7.82 1.7.81 1.7.80 1.7.79 1.7.78 1.7.77 1.7.76 1.7.75 1.7.74 1.7.71 1.7.70 1.7.69 1.7.66 1.7.65 1.7.64 1.7.63 1.7.62 1.7.61 1.7.59 1.7.58 1.7.57 1.7.56 1.7.55 1.7.54 1.7.53 1.7.52 1.7.51 1.7.49 1.7.44 1.7.43 1.7.42 1.7.41 1.7.39 1.7.38 1.7.37 1.7.36 1.7.34 1.7.33 1.7.31 1.7.30 1.7.29 1.7.28 1.7.27 1.7.26 1.7.25 1.7.24 1.7.23 1.7.22 1.7.21 1.7.20 1.7.19 1.7.18 1.7.17 1.7.16 1.7.15 1.7.14 1.7.13 1.7.12 1.7.11 1.7.10 1.7.9 1.7.8 1.7.7 1.7.6 1.7.5 1.7.4 1.7.3 1.7.2 1.7.1 1.7.0 1.6.20 1.6.19 1.6.18 1.6.17 1.6.16 1.6.15 1.6.14 1.6.13 1.6.12 1.6.11 1.6.10 1.6.9 1.6.8 1.6.7 1.6.6 1.6.5 1.6.4 1.6.3 1.5.2 1.5.1 1.5.0 1.4.9 1.4.8 1.4.7 1.4.6 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.3.2 1.3.1 1.3.0 1.2.10 1.2.9 1.2.8 1.2.7 1.2.5 1.2.4 1.2.2 1.2.1 1.2.0 1.1.0 1.0.0

A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more

Current section

Files

Jump to
phoenix_kit lib phoenix_kit_web live modules sitemaps settings.ex
Raw

lib/phoenix_kit_web/live/modules/sitemaps/settings.ex

defmodule PhoenixKitWeb.Live.Modules.Sitemaps.Settings do
@moduledoc """
LiveView for sitemap configuration and management.
Provides admin interface for:
- Enabling/disabling sitemap module
- Configuring data sources (entities, blogs, pages, static)
- Setting HTML sitemap style
- Manual sitemap regeneration
- Viewing generation statistics
"""
use PhoenixKitWeb, :live_view
use Gettext, backend: PhoenixKitWeb.Gettext
alias PhoenixKit.Settings
alias PhoenixKit.Sitemap
alias PhoenixKit.Sitemap.Generator
alias PhoenixKit.Utils.Date, as: UtilsDate
alias PhoenixKit.Utils.Routes
@impl true
def mount(params, _session, socket) do
locale = params["locale"] || "en"
project_title = Settings.get_setting("project_title", "PhoenixKit")
site_url = Settings.get_setting("site_url", "")
config = Sitemap.get_config()
socket =
socket
|> assign(:page_title, "Sitemap Settings")
|> assign(:project_title, project_title)
|> assign(:current_locale, locale)
|> assign(:current_path, Routes.path("/admin/settings/sitemap", locale: locale))
|> assign(:config, config)
|> assign(:site_url, site_url)
|> assign(:generating, false)
|> assign(:preview_mode, nil)
|> assign(:preview_content, nil)
|> assign(:show_preview, false)
|> assign(:show_html_preview, false)
{:ok, socket}
end
@impl true
def handle_params(_params, _url, socket) do
{:noreply, socket}
end
@impl true
def handle_event("toggle_sitemap", _params, socket) do
new_enabled = !socket.assigns.config.enabled
result =
if new_enabled do
Sitemap.enable_system()
else
Sitemap.disable_system()
end
case result do
{:ok, _} ->
config = Sitemap.get_config()
message = if new_enabled, do: "Sitemap enabled", else: "Sitemap disabled"
{:noreply,
socket
|> assign(:config, config)
|> put_flash(:info, message)}
{:error, _} ->
{:noreply, put_flash(socket, :error, "Failed to update sitemap status")}
end
end
@impl true
def handle_event("toggle_source", %{"source" => source}, socket) do
# Router discovery uses different key pattern
key =
if source == "router_discovery" do
"sitemap_router_discovery_enabled"
else
"sitemap_include_#{source}"
end
current = Settings.get_boolean_setting(key, true)
case Settings.update_boolean_setting(key, !current) do
{:ok, _} ->
config = Sitemap.get_config()
{:noreply, assign(socket, :config, config)}
{:error, _} ->
{:noreply, put_flash(socket, :error, "Failed to update source setting")}
end
end
@impl true
def handle_event("toggle_html", _params, socket) do
current = socket.assigns.config.html_enabled
case Settings.update_boolean_setting("sitemap_html_enabled", !current) do
{:ok, _} ->
config = Sitemap.get_config()
{:noreply, assign(socket, :config, config)}
{:error, _} ->
{:noreply, put_flash(socket, :error, "Failed to update HTML sitemap setting")}
end
end
@impl true
def handle_event("toggle_schedule", _params, socket) do
current = socket.assigns.config.schedule_enabled
case Settings.update_boolean_setting("sitemap_schedule_enabled", !current) do
{:ok, _} ->
config = Sitemap.get_config()
{:noreply, assign(socket, :config, config)}
{:error, _} ->
{:noreply, put_flash(socket, :error, "Failed to update schedule setting")}
end
end
@impl true
def handle_event("update_style", %{"style" => style}, socket) do
case Settings.update_setting("sitemap_html_style", style) do
{:ok, _} ->
config = Sitemap.get_config()
{:noreply, assign(socket, :config, config)}
{:error, _} ->
{:noreply, put_flash(socket, :error, "Failed to update style")}
end
end
@impl true
def handle_event("update_interval", %{"interval" => interval_str}, socket) do
case Integer.parse(interval_str) do
{interval, _} when interval > 0 ->
case Settings.update_setting("sitemap_schedule_interval_hours", interval_str) do
{:ok, _} ->
config = Sitemap.get_config()
{:noreply, assign(socket, :config, config)}
{:error, _} ->
{:noreply, put_flash(socket, :error, "Failed to update interval")}
end
_ ->
{:noreply, put_flash(socket, :error, "Invalid interval value")}
end
end
@impl true
def handle_event("regenerate", _params, socket) do
socket = assign(socket, :generating, true)
# Get base URL for generation
base_url = Sitemap.get_base_url()
if base_url != "" do
# Collect entries first to get URL count
entries = Generator.collect_all_entries(base_url: base_url)
url_count = length(entries)
# Get XSL style from config (mapped from html_style)
xsl_style = get_xsl_style(socket.assigns.config.html_style)
opts = [
base_url: base_url,
cache: true,
xsl_style: xsl_style,
xsl_enabled: socket.assigns.config.html_enabled
]
case Generator.generate_xml(opts) do
{:ok, _xml} ->
# Update stats with actual URL count
Sitemap.update_generation_stats(%{url_count: url_count})
config = Sitemap.get_config()
{:noreply,
socket
|> assign(:generating, false)
|> assign(:config, config)
|> put_flash(:info, "Sitemap regenerated successfully (#{url_count} URLs)")}
{:ok, _xml, _parts} ->
Sitemap.update_generation_stats(%{url_count: url_count})
config = Sitemap.get_config()
{:noreply,
socket
|> assign(:generating, false)
|> assign(:config, config)
|> put_flash(:info, "Sitemap regenerated with index (#{url_count} URLs)")}
{:error, reason} ->
{:noreply,
socket
|> assign(:generating, false)
|> put_flash(:error, "Regeneration failed: #{inspect(reason)}")}
end
else
{:noreply,
socket
|> assign(:generating, false)
|> put_flash(:error, "Please configure Base URL before generating")}
end
end
@impl true
def handle_event("preview", %{"type" => _type}, socket) do
base_url = Sitemap.get_base_url()
xsl_style = get_xsl_style(socket.assigns.config.html_style)
opts = [
base_url: base_url,
cache: false,
xsl_style: xsl_style,
xsl_enabled: socket.assigns.config.html_enabled
]
content =
case Generator.generate_xml(opts) do
{:ok, xml} -> xml
{:ok, xml, _parts} -> xml
_ -> "Error generating XML preview"
end
{:noreply,
socket
|> assign(:preview_mode, "xml")
|> assign(:preview_content, content)
|> assign(:show_preview, true)}
end
@impl true
def handle_event("close_preview", _params, socket) do
{:noreply,
socket
|> assign(:show_preview, false)
|> assign(:preview_mode, nil)
|> assign(:preview_content, nil)}
end
@impl true
def handle_event("preview_html", _params, socket) do
{:noreply, assign(socket, :show_html_preview, true)}
end
@impl true
def handle_event("close_html_preview", _params, socket) do
{:noreply, assign(socket, :show_html_preview, false)}
end
@impl true
def handle_event("invalidate_cache", _params, socket) do
Generator.invalidate_cache()
{:noreply,
socket
|> put_flash(:info, "Sitemap cache cleared")}
end
# Maps old HTML style names to new XSL style names
# hierarchical -> cards, grouped -> table, flat -> minimal
def get_xsl_style(html_style) do
case html_style do
"hierarchical" -> "cards"
"grouped" -> "table"
"flat" -> "minimal"
style when style in ["table", "cards", "minimal"] -> style
_ -> "table"
end
end
# Format ISO8601 timestamp string to human-readable format
def format_timestamp(nil), do: "Never"
def format_timestamp(iso_string) when is_binary(iso_string) do
case DateTime.from_iso8601(iso_string) do
{:ok, dt, _} ->
# Convert to NaiveDateTime for UtilsDate
ndt = DateTime.to_naive(dt)
UtilsDate.format_datetime_full_with_user_format(ndt)
_ ->
iso_string
end
end
def format_timestamp(_), do: "Never"
end