# `PhoenixKit.Modules.Sitemap`
[🔗](https://github.com/BeamLabEU/phoenix_kit/blob/v1.7.165/lib/modules/sitemap/sitemap.ex#L1)

Sitemap generation and management context for PhoenixKit.

This module provides functions for generating and managing XML and HTML sitemaps
using Settings for configuration storage. Sitemaps help search engines discover
and index site content.

## Core Functions

### System Control

- `enabled?/0` - Check if sitemap module is enabled
- `enable_system/0` - Enable sitemap module
- `disable_system/0` - Disable sitemap module

### Configuration

- `get_config/0` - Get current sitemap configuration
- `get_base_url/0` - Get base URL for sitemap generation
- `build_url/1` - Build full URL from relative path
- `schedule_enabled?/0` - Check if automatic generation is enabled
- `get_schedule_interval_hours/0` - Get generation interval in hours

### Content Settings

- `include_entities?/0` - Check if entities should be included (all entity types)
- `include_blogs?/0` - Check if blog posts should be included
- `include_static?/0` - Check if static pages should be included

### HTML Sitemap

- `html_enabled?/0` - Check if HTML sitemap is enabled
- `get_html_style/0` - Get HTML sitemap display style
- `get_default_changefreq/0` - Get default change frequency
- `get_default_priority/0` - Get default URL priority

### Generation

- `regenerate/1` - Trigger sitemap regeneration
- `update_generation_stats/1` - Update generation statistics
- `get_cached_xml/0` - Get cached XML sitemap
- `get_cached_html/0` - Get cached HTML sitemap
- `invalidate_cache/0` - Clear sitemap cache

## Settings Keys

All configuration is stored in the Settings system:

- `sitemap_enabled` - Enable/disable sitemap module (boolean)
- `sitemap_schedule_enabled` - Enable automatic generation (boolean)
- `sitemap_schedule_interval_hours` - Generation interval (integer)
- `sitemap_include_entities` - Include entities in sitemap (boolean, all entity types)
- `sitemap_include_blogs` - Include blog posts (boolean)
- `sitemap_include_static` - Include static pages (boolean)
- `sitemap_base_url` - Base URL for sitemap (string, fallback to site_url)
- `sitemap_html_enabled` - Enable HTML sitemap (boolean)
- `sitemap_html_style` - HTML display style (hierarchical/flat/grouped)
- `sitemap_default_changefreq` - Default change frequency (string)
- `sitemap_default_priority` - Default URL priority (string)
- `sitemap_last_generated` - Last generation timestamp (ISO8601)
- `sitemap_url_count` - Number of URLs in sitemap (integer)

## Usage Examples

    # Check if sitemap module is enabled
    if PhoenixKit.Modules.Sitemap.enabled?() do
      # Generate sitemap
      PhoenixKit.Modules.Sitemap.regenerate(scope)
    end

    # Get configuration
    config = PhoenixKit.Modules.Sitemap.get_config()
    # => %{
    #   enabled: true,
    #   schedule_enabled: true,
    #   schedule_interval_hours: 24,
    #   include_entities: true,
    #   include_blogs: true,
    #   include_static: true,
    #   base_url: "https://example.com",
    #   html_enabled: true,
    #   html_style: "hierarchical",
    #   default_changefreq: "weekly",
    #   default_priority: "0.5",
    #   last_generated: "2025-12-02T10:30:00Z",
    #   url_count: 150
    # }

    # Build full URLs
    url = PhoenixKit.Modules.Sitemap.build_url("/about")
    # => "https://example.com/about"

    # Get cached sitemaps
    xml = PhoenixKit.Modules.Sitemap.get_cached_xml()
    html = PhoenixKit.Modules.Sitemap.get_cached_html()

    # Invalidate cache after regeneration
    PhoenixKit.Modules.Sitemap.invalidate_cache()

# `build_url`

```elixir
@spec build_url(String.t()) :: String.t()
```

Builds a full URL from a relative path using the configured base URL.

## Examples

    iex> PhoenixKit.Modules.Sitemap.build_url("/about")
    "https://example.com/about"

    iex> PhoenixKit.Modules.Sitemap.build_url("contact")
    "https://example.com/contact"

# `cache_html`

```elixir
@spec cache_html(String.t()) :: {:ok, any()} | {:error, any()}
```

Stores HTML sitemap content in cache.

## Examples

    iex> PhoenixKit.Modules.Sitemap.cache_html(html_content)
    {:ok, %PhoenixKit.Settings.Setting{}}

# `cache_xml`

```elixir
@spec cache_xml(String.t()) :: {:ok, any()} | {:error, any()}
```

Stores XML sitemap content in cache.

## Examples

    iex> PhoenixKit.Modules.Sitemap.cache_xml(xml_content)
    {:ok, %PhoenixKit.Settings.Setting{}}

# `clear_generation_stats`

```elixir
@spec clear_generation_stats() :: :ok
```

Clears generation statistics.

Called when cache is invalidated to indicate the sitemap file no longer exists.
Next request will regenerate the sitemap.

## Examples

    iex> PhoenixKit.Modules.Sitemap.clear_generation_stats()
    :ok

# `disable_system`

```elixir
@spec disable_system() :: {:ok, any()} | {:error, any()}
```

Disables the sitemap module.

## Examples

    iex> PhoenixKit.Modules.Sitemap.disable_system()
    {:ok, %PhoenixKit.Settings.Setting{}}

# `enable_system`

```elixir
@spec enable_system() :: {:ok, any()} | {:error, any()}
```

Enables the sitemap module.

## Examples

    iex> PhoenixKit.Modules.Sitemap.enable_system()
    {:ok, %PhoenixKit.Settings.Setting{}}

# `enabled?`

```elixir
@spec enabled?() :: boolean()
```

Returns true when the sitemap module is enabled.

## Examples

    iex> PhoenixKit.Modules.Sitemap.enabled?()
    false

    iex> PhoenixKit.Modules.Sitemap.enable_system()
    iex> PhoenixKit.Modules.Sitemap.enabled?()
    true

# `flat_mode?`

```elixir
@spec flat_mode?() :: boolean()
```

Returns true when sitemap is in flat mode (single `<urlset>`).

Flat mode is active when Router Discovery is enabled — all URLs from all
sources are merged into a single sitemap.xml. When Router Discovery is off,
index mode is used with per-module sitemap files.

# `get_base_url`

```elixir
@spec get_base_url() :: String.t()
```

Returns the base URL for sitemap generation.

Uses site_url from Settings. Returns empty string if not configured.

## Examples

    iex> PhoenixKit.Modules.Sitemap.get_base_url()
    "https://example.com"

# `get_cached_html`

```elixir
@spec get_cached_html() :: String.t() | nil
```

Returns the cached HTML sitemap content.

Returns nil if no cached sitemap exists.

## Examples

    iex> PhoenixKit.Modules.Sitemap.get_cached_html()
    "<html>...</html>"

# `get_cached_xml`

```elixir
@spec get_cached_xml() :: String.t() | nil
```

Returns the cached XML sitemap content.

Returns nil if no cached sitemap exists.

## Examples

    iex> PhoenixKit.Modules.Sitemap.get_cached_xml()
    "<?xml version="1.0" encoding="UTF-8"?>\n<urlset>...</urlset>"

# `get_config`

```elixir
@spec get_config() :: map()
```

Returns the current sitemap configuration as a map.

## Examples

    iex> PhoenixKit.Modules.Sitemap.get_config()
    %{
      enabled: true,
      schedule_enabled: true,
      schedule_interval_hours: 24,
      include_entities: true,
      include_blogs: true,
      include_pages: true,
      include_static: true,
      base_url: "https://example.com",
      html_enabled: true,
      html_style: "hierarchical",
      default_changefreq: "weekly",
      default_priority: "0.5",
      last_generated: "2025-12-02T10:30:00Z",
      url_count: 150
    }

# `get_default_changefreq`

```elixir
@spec get_default_changefreq() :: String.t()
```

Returns the default change frequency for sitemap URLs.

## Examples

    iex> PhoenixKit.Modules.Sitemap.get_default_changefreq()
    "weekly"

# `get_default_priority`

```elixir
@spec get_default_priority() :: String.t()
```

Returns the default priority for sitemap URLs.

## Examples

    iex> PhoenixKit.Modules.Sitemap.get_default_priority()
    "0.5"

# `get_html_style`

```elixir
@spec get_html_style() :: String.t()
```

Returns the HTML sitemap display style.

Valid values: "hierarchical", "flat", "grouped"

## Examples

    iex> PhoenixKit.Modules.Sitemap.get_html_style()
    "hierarchical"

# `get_last_generated`

```elixir
@spec get_last_generated() :: String.t() | nil
```

Returns the timestamp when sitemap was last generated.

Returns ISO8601 timestamp string or nil if never generated.

## Examples

    iex> PhoenixKit.Modules.Sitemap.get_last_generated()
    "2025-12-02T10:30:00Z"

# `get_module_stats`

```elixir
@spec get_module_stats() :: [map()]
```

Returns per-module generation stats from Settings.

# `get_schedule_interval_hours`

```elixir
@spec get_schedule_interval_hours() :: integer()
```

Returns the scheduled generation interval in hours.

## Examples

    iex> PhoenixKit.Modules.Sitemap.get_schedule_interval_hours()
    24

# `get_url_count`

```elixir
@spec get_url_count() :: integer()
```

Returns the number of URLs in the current sitemap.

## Examples

    iex> PhoenixKit.Modules.Sitemap.get_url_count()
    150

# `html_enabled?`

```elixir
@spec html_enabled?() :: boolean()
```

Returns true if HTML sitemap generation is enabled.

## Examples

    iex> PhoenixKit.Modules.Sitemap.html_enabled?()
    true

# `include_blogs?`

```elixir
@spec include_blogs?() :: boolean()
```

Returns true if blog posts should be included in sitemap.

## Examples

    iex> PhoenixKit.Modules.Sitemap.include_blogs?()
    true

# `include_entities?`

```elixir
@spec include_entities?() :: boolean()
```

Returns true if entities should be included in sitemap.

## Examples

    iex> PhoenixKit.Modules.Sitemap.include_entities?()
    true

# `include_publishing?`

```elixir
@spec include_publishing?() :: boolean()
```

Alias for `include_blogs?/0` - reads the same `sitemap_include_blogs` key.

# `include_registration?`

```elixir
@spec include_registration?() :: boolean()
```

Returns true if the registration page should be included in the sitemap.

Default: false (registration pages are excluded by default).

# `include_shop?`

```elixir
@spec include_shop?() :: boolean()
```

Returns true if shop pages should be included in sitemap.

## Examples

    iex> PhoenixKit.Modules.Sitemap.include_shop?()
    true

# `include_static?`

```elixir
@spec include_static?() :: boolean()
```

Returns true if static pages should be included in sitemap.

## Examples

    iex> PhoenixKit.Modules.Sitemap.include_static?()
    true

# `invalidate_cache`

```elixir
@spec invalidate_cache() :: :ok
```

Invalidates sitemap cache.

This should be called after regenerating sitemaps to ensure
fresh content is served.

## Examples

    iex> PhoenixKit.Modules.Sitemap.invalidate_cache()
    :ok

# `publishing_split_by_group?`

```elixir
@spec publishing_split_by_group?() :: boolean()
```

Returns true if publishing posts should be split into per-blog sitemap files.

Default: false (all publishing posts in a single file).

# `regenerate`

```elixir
@spec regenerate(any()) :: {:ok, map()} | {:error, any()}
```

Triggers sitemap regeneration.

This function will be called by the Generator module to perform the actual
sitemap generation. Pass optional scope for audit logging.

## Examples

    iex> PhoenixKit.Modules.Sitemap.regenerate(scope)
    {:ok, %{xml: xml_content, html: html_content, url_count: 150}}

# `router_discovery_enabled?`

```elixir
@spec router_discovery_enabled?() :: boolean()
```

Returns true if router discovery should be enabled.

Router discovery automatically scans the parent application's router
for GET routes and includes them in the sitemap.

## Examples

    iex> PhoenixKit.Modules.Sitemap.router_discovery_enabled?()
    true

# `schedule_enabled?`

```elixir
@spec schedule_enabled?() :: boolean()
```

Returns true if automatic sitemap generation is enabled.

## Examples

    iex> PhoenixKit.Modules.Sitemap.schedule_enabled?()
    true

# `update_generation_stats`

```elixir
@spec update_generation_stats(map()) :: {:ok, map()} | {:error, any()}
```

Updates generation statistics after sitemap creation.

Accepts a map with :url_count and optionally :timestamp.

## Examples

    iex> PhoenixKit.Modules.Sitemap.update_generation_stats(%{url_count: 150})
    {:ok, %{last_generated: "2025-12-02T10:30:00Z", url_count: 150}}

    iex> PhoenixKit.Modules.Sitemap.update_generation_stats(%{
    ...>   url_count: 150,
    ...>   timestamp: ~U[2025-12-02 10:30:00Z]
    ...> })
    {:ok, %{last_generated: "2025-12-02T10:30:00Z", url_count: 150}}

# `update_module_stats`

```elixir
@spec update_module_stats([map()]) :: {:ok, any()} | {:error, any()}
```

Updates per-module generation stats in Settings.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
