Packages
phoenix_kit
1.3.2
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
Current section
Files
lib/phoenix_kit/config.ex
defmodule PhoenixKit.Config do
@moduledoc """
Configuration management system for PhoenixKit.
This module provides a centralized way to manage PhoenixKit configuration.
## Usage
# Get all configuration
config = PhoenixKit.Config.get_all()
# Get specific values
repo = PhoenixKit.Config.get(:repo)
mailer = PhoenixKit.Config.get(:mailer, PhoenixKit.Mailer)
## Configuration Keys
- `:repo` - Ecto repository module (required)
- `:mailer` - Mailer module for sending emails
- `:host` - Application hostname
- `:port` - Application port
- `:layout_module` - Custom layout configuration
- `:from_email` - Default sender email address for notifications
- `:from_name` - Default sender name for notifications (default: "PhoenixKit")
"""
@default_config [
repo: nil,
mailer: nil,
scheme: "http",
host: "localhost",
port: 4000,
url_prefix: "/phoenix_kit",
layouts_module: nil,
phoenix_version_strategy: nil,
from_email: nil,
from_name: "PhoenixKit"
]
@doc """
Gets all PhoenixKit configuration.
"""
@spec get_all() :: Keyword.t()
def get_all do
app_config = Application.get_all_env(:phoenix_kit)
Keyword.merge(@default_config, app_config)
end
@doc """
Gets a specific configuration value.
"""
@spec get(atom()) :: {:ok, any()} | :not_found
def get(key) when is_atom(key) do
config = get_all()
case Keyword.get(config, key) do
nil -> :not_found
value -> {:ok, value}
end
end
@doc """
Gets a specific configuration value with a default.
## Examples
iex> PhoenixKit.Config.get(:mailer, PhoenixKit.Mailer)
MyApp.Mailer
iex> PhoenixKit.Config.get(:nonexistent, :default)
:default
"""
@spec get(atom(), any()) :: any()
def get(key, default) when is_atom(key) do
case get(key) do
{:ok, value} -> value
:not_found -> default
end
end
@doc """
Gets the configured mailer module.
Returns the configured mailer or falls back to PhoenixKit.Mailer.
## Examples
iex> PhoenixKit.Config.get_mailer()
MyApp.Mailer
"""
@spec get_mailer() :: module()
def get_mailer do
case get(:mailer) do
{:ok, mailer} when is_atom(mailer) -> mailer
_ -> PhoenixKit.Mailer
end
end
@doc """
Gets configured host with an optional port or default value.
"""
@spec get_base_url() :: String.t()
def get_base_url do
host =
case get(:host) do
{:ok, host} -> host
_ -> "localhost"
end
scheme =
case get(:scheme) do
{:ok, scheme} -> scheme
_ -> "http"
end
port =
case get(:port) do
{:ok, port} when port not in [80, 443] -> ":#{port}"
_ -> ":4000"
end
"#{scheme}://#{host}#{port}"
end
@doc """
Gets the base URL dynamically from the parent Phoenix Endpoint if available,
otherwise falls back to the static configuration.
This function automatically detects the correct URL from the running Phoenix
application, which is especially useful in development mode where the port
might be different from the default configuration.
## Examples
iex> PhoenixKit.Config.get_dynamic_base_url()
"http://localhost:4001" # from Phoenix Endpoint
iex> PhoenixKit.Config.get_dynamic_base_url()
"http://localhost:4000" # fallback to static config
"""
@spec get_dynamic_base_url() :: String.t()
def get_dynamic_base_url do
case get_parent_endpoint_url() do
{:ok, url} -> url
:error -> get_base_url()
end
end
@doc """
Gets the parent Phoenix Endpoint URL if the endpoint is available and running.
Returns `{:ok, url}` if successful, `:error` if the endpoint cannot be found
or accessed.
"""
@spec get_parent_endpoint_url() :: {:ok, String.t()} | :error
def get_parent_endpoint_url do
with {:ok, endpoint} <- get_parent_endpoint(),
true <- function_exported?(endpoint, :url, 0) do
try do
url = endpoint.url()
{:ok, url}
rescue
_ -> :error
end
else
_ -> :error
end
end
@doc """
Gets the parent application's Phoenix Endpoint module.
This function attempts to detect the main application's endpoint that is using
PhoenixKit as a dependency.
Returns `{:ok, endpoint_module}` if found, `:error` otherwise.
"""
@spec get_parent_endpoint() :: {:ok, module()} | :error
def get_parent_endpoint do
case get_parent_app() do
nil ->
:error
app_name ->
base_module = app_name |> to_string() |> Macro.camelize()
potential_endpoints = [
Module.concat([base_module <> "Web", "Endpoint"]),
Module.concat([base_module, "Endpoint"])
]
Enum.reduce_while(potential_endpoints, :error, fn endpoint, _acc ->
if Code.ensure_loaded?(endpoint) and function_exported?(endpoint, :url, 0) do
{:halt, {:ok, endpoint}}
else
{:cont, :error}
end
end)
end
end
@doc """
Gets configured prefix for urls or default value.
"""
@spec get_url_prefix() :: String.t()
def get_url_prefix do
case get(:url_prefix, "/phoenix_kit") do
nil -> "/"
"" -> "/"
value -> value
end
end
@doc """
Gets the parent application name that is using PhoenixKit.
This function attempts to detect the main application that has included
PhoenixKit as a dependency.
"""
@spec get_parent_app() :: atom() | nil
def get_parent_app do
# Get the application of the configured repo to determine parent app
case get(:repo) do
{:ok, repo_module} when is_atom(repo_module) ->
# Extract app name from repo module (e.g. MyApp.Repo -> :my_app)
repo_module
|> Module.split()
|> hd()
|> Macro.underscore()
|> String.to_atom()
_ ->
# Fallback: try to find the main application from the loaded applications
Application.loaded_applications()
|> Enum.find(fn {app, _, _} ->
app != :phoenix_kit and
app != :kernel and
app != :stdlib and
app != :elixir and
not String.starts_with?(to_string(app), "ex_")
end)
|> case do
{app, _, _} -> app
nil -> nil
end
end
end
@doc """
Validates that required configuration is present.
Raises an exception if any required keys are missing.
## Examples
PhoenixKit.Config.validate_required!([:repo, :secret_key_base])
"""
def validate_required!(required_keys) do
config = get_all()
missing_keys =
required_keys
|> Enum.reject(&Keyword.has_key?(config, &1))
if length(missing_keys) > 0 do
raise """
Missing required PhoenixKit configuration keys: #{inspect(missing_keys)}
Current configuration: #{inspect(Keyword.keys(config))}
Please add the missing keys to your configuration:
config :phoenix_kit,
#{Enum.map_join(missing_keys, ",\n ", &"#{&1}: YourValue")}
"""
end
:ok
end
end