Packages

phoenix_kit

1.7.181
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 modules sitemap sources source.ex
Raw

lib/modules/sitemap/sources/source.ex

defmodule PhoenixKit.Modules.Sitemap.Sources.Source do
@moduledoc """
Behaviour for sitemap data sources.
Each source module must implement this behaviour to provide URL entries
for sitemap generation.
## Required Callbacks
- `source_name/0` - Unique atom identifier for the source
- `enabled?/0` - Whether this source is active
- `collect/1` - Collect URL entries from this source
## Optional Callbacks
- `sitemap_filename/0` - Custom filename for the module's sitemap file
- `sub_sitemaps/1` - Split into multiple sub-sitemap files (e.g., per-blog, per-entity-type)
- `sitemap_settings_schema/0` - Declare source-specific settings for the admin UI
"""
require Logger
alias PhoenixKit.Modules.Sitemap.UrlEntry
@typedoc """
Describes one source-specific setting for the admin settings UI.
- `key` - the `PhoenixKit.Settings` key this field reads/writes
- `type` - controls both the input widget and how the stored string is
parsed (`:boolean` -> toggle, `:string` -> text input, `:integer` -> number input)
- `label` - field label shown to the admin
- `help` - optional helper text shown below the label
- `default` - value used when the setting has never been saved
"""
@type settings_field :: %{
key: String.t(),
type: :boolean | :string | :integer,
label: String.t(),
help: String.t() | nil,
default: term()
}
@doc """
Returns the unique name/identifier for this source.
"""
@callback source_name() :: atom()
@doc """
Checks if this source is enabled and should be included in sitemap.
"""
@callback enabled?() :: boolean()
@doc """
Collects all URL entries from this source.
"""
@callback collect(opts :: keyword()) :: [UrlEntry.t()]
@doc """
Returns the base filename for this source's sitemap file (without .xml extension).
Default: `"sitemap-\#{source_name()}"`
"""
@callback sitemap_filename() :: String.t()
@doc """
Returns a list of sub-sitemaps for sources that produce multiple files.
Return `nil` for a single file, or a list of `{group_name, entries}` tuples
for per-group splitting (e.g., per-blog, per-entity-type).
Each group will be saved as `sitemap-{source}-{group_name}.xml`.
"""
@callback sub_sitemaps(opts :: keyword()) :: [{String.t(), [UrlEntry.t()]}] | nil
@doc """
Declares source-specific settings for the sitemap admin settings page.
Optional. A source that implements this returns a list of field
descriptors; the settings page renders one input per field (grouped
under the source's name), reads/writes each through `PhoenixKit.Settings`
using its `key` and `default`, and invalidates the sitemap cache on save
— the same way the page's built-in settings work.
Only add this for settings that don't already have a UI. Don't
reimplement fields the core sitemap settings page already exposes (e.g.
the built-in `sitemap_include_*` toggles).
## Example
def sitemap_settings_schema do
[
%{
key: "sitemap_entities_include_index",
type: :boolean,
label: "Include entity index pages",
help: "Adds the /entities listing page alongside individual entries",
default: true
}
]
end
"""
@callback sitemap_settings_schema() :: [settings_field()]
@optional_callbacks [sitemap_filename: 0, sub_sitemaps: 1, sitemap_settings_schema: 0]
@doc """
Helper function to check if a source module is valid.
"""
@spec valid_source?(module()) :: boolean()
def valid_source?(module) when is_atom(module) do
case Code.ensure_loaded(module) do
{:module, _} ->
function_exported?(module, :source_name, 0) and
function_exported?(module, :enabled?, 0) and
function_exported?(module, :collect, 1)
{:error, _} ->
false
end
end
def valid_source?(_), do: false
@doc """
Returns the sitemap filename for a source module.
Calls the optional `sitemap_filename/0` callback if implemented,
otherwise returns `"sitemap-\#{source_name()}"`.
"""
@spec get_sitemap_filename(module()) :: String.t()
def get_sitemap_filename(source_module) do
if function_exported?(source_module, :sitemap_filename, 0) do
source_module.sitemap_filename()
else
"sitemap-#{source_module.source_name()}"
end
end
@doc """
Returns sub-sitemaps for a source module, or nil if not implemented.
"""
@spec get_sub_sitemaps(module(), keyword()) :: [{String.t(), [UrlEntry.t()]}] | nil
def get_sub_sitemaps(source_module, opts \\ []) do
if function_exported?(source_module, :sub_sitemaps, 1) do
source_module.sub_sitemaps(opts)
else
nil
end
end
@doc """
Returns the settings schema for a source module.
Calls the optional `sitemap_settings_schema/0` callback if implemented,
otherwise returns `[]` (no source-specific settings to render).
"""
@spec get_settings_schema(module()) :: [settings_field()]
def get_settings_schema(source_module) do
if function_exported?(source_module, :sitemap_settings_schema, 0) do
source_module.sitemap_settings_schema()
else
[]
end
end
@doc """
Safely collects entries from a source, handling errors gracefully.
"""
@spec safe_collect(module(), keyword()) :: [UrlEntry.t()]
def safe_collect(source_module, opts \\ []) do
force = Keyword.get(opts, :force, false)
if valid_source?(source_module) and (force or source_module.enabled?()) do
source_module.collect(opts)
else
[]
end
rescue
error ->
Logger.warning(
"Sitemap source #{inspect(source_module)} failed to collect: #{inspect(error)}"
)
[]
end
end