Logic for resolving entity and record URLs based on router introspection, entity settings, and global configuration.
Extracted from SitemapSource to provide a shared API for public URL generation.
Summary
Functions
Adds a language prefix for public front-end URLs.
Substitutes :slug and :id placeholders in a URL pattern with record data.
Adds a language prefix to a path for the sitemap.
Builds a cache of all routes for efficient lookups.
Builds a full URL by prepending a base URL.
Resolves the index-page path for an entity using a pre-built routes cache.
Resolves the URL pattern for an entity using a pre-built routes cache.
Resolves the constant locale path-prefix for a (language, is_default)
pair — "/en", "", etc.
Returns true when the site is effectively single-language.
Types
Functions
Adds a language prefix for public front-end URLs.
Policy:
- Single-language mode → no prefix
- Locale is
nil, empty, or malformed → no prefix - Locale matches the primary language → follows the site-wide
Languages.default_language_no_prefix?/0setting (when ON, skip the prefix; when OFF, include it —/<base>) - Otherwise →
/<base>prefix (where<base>is a validated base code)
This matches the convention used by PhoenixKit.Utils.Routes.path/2
and PhoenixKit.Utils.Routes.admin_path/2, which both honor the same
setting.
The base code is validated against ^[a-z]{2,3}$ before interpolation, so
caller-supplied locales (for example from request params) cannot inject
arbitrary path segments.
Substitutes :slug and :id placeholders in a URL pattern with record data.
:slug falls back to the record UUID when the slug is nil. Patterns without
placeholders are returned unchanged.
Adds a language prefix to a path for the sitemap.
Used by PhoenixKitEntities.SitemapSource for hreflang-aware sitemap
entries. The prefix decision is delegated to the framework-shared
PhoenixKit.Modules.Sitemap.LocalePath.emit_prefix?/2 (the same policy
every core sitemap source uses), so entities' sitemap stays consistent
with publishing/posts/static. This helper owns only the formatting.
Pass is_default: true only when language is the site's primary —
emit_prefix?/2 trusts that flag. Consumers building public links
should prefer add_public_locale_prefix/2, which derives primary-ness
from the locale itself.
Resolves the site-wide locale settings on every call. When building
many URLs for the same (language, is_default) pair — e.g. a sitemap
run — resolve locale_prefix/2 once and prepend it instead.
@spec build_routes_cache() :: routes_cache()
Builds a cache of all routes for efficient lookups.
For hot loops (e.g. rendering a listing of records), build the cache once
via this function and pass it as :routes_cache to EntityData.public_path/3.
Builds a full URL by prepending a base URL.
If base_url is nil, falls back to the site_url setting (or empty string).
@spec get_index_path_cached(map(), routes_cache()) :: String.t() | nil
Resolves the index-page path for an entity using a pre-built routes cache.
Used by the sitemap source to emit index entries (e.g. /products alongside
/products/:slug). Returns nil if no index path can be resolved.
@spec get_url_pattern_cached(map(), routes_cache()) :: String.t() | nil
Resolves the URL pattern for an entity using a pre-built routes cache.
Resolution chain: entity.settings["sitemap_url_pattern"] → router introspection
(explicit or catchall) → sitemap_entity_<name>_pattern setting → global
sitemap_entities_pattern. Returns nil if none match.
Resolves the constant locale path-prefix for a (language, is_default)
pair — "/en", "", etc.
The decision (via LocalePath.emit_prefix?/2) and base-code extraction
read site-wide language settings, which are invariant across a single
sitemap generation. Resolve this once and prepend the result to each
record's path rather than calling build_path_with_language/3 per URL,
which re-reads those settings every time.
@spec single_language_mode?() :: boolean()
Returns true when the site is effectively single-language.
True when the Languages module is disabled or only one language is enabled; also true if the lookup fails (defensive fallback).