PhoenixKit.Modules.Publishing.Posts (PhoenixKitPublishing v0.1.7)

Copy Markdown View Source

Post CRUD operations for the Publishing module.

Handles creating, reading, updating, and trashing posts, as well as slug/version/language extraction and timestamp management.

Posts are routing shells — versions are the source of truth for status, published_at, and metadata (featured_image, tags, seo, description). Content rows hold per-language title + body + url_slug.

Summary

Functions

Counts posts on a specific date for a group.

Creates a new post for the given publishing group using the current timestamp.

Returns true when the given post is a DB-backed post (has a UUID).

Finds a post by a previous URL slug (for 301 redirects).

Finds a post by URL slug from the database.

Lists posts for a given publishing group slug.

Lists posts filtered by status (e.g. 'trashed', 'published').

Lists raw DB post records for a group, optionally filtered by status.

Lists time values for posts on a specific date.

Restores a trashed post by UUID, clearing its trashed_at timestamp.

Soft-deletes a post by UUID (sets trashed_at timestamp).

Updates a post in the database.

Updates version.data with metadata like featured_image_uuid, description, seo_title, tags, etc.

Functions

count_posts_on_date(group_slug, date)

@spec count_posts_on_date(String.t(), Date.t() | String.t()) :: non_neg_integer()

Counts posts on a specific date for a group.

create_post(group_slug, opts \\ %{})

@spec create_post(String.t(), map() | keyword()) :: {:ok, map()} | {:error, any()}

Creates a new post for the given publishing group using the current timestamp.

db_post?(post)

@spec db_post?(map()) :: boolean()

Returns true when the given post is a DB-backed post (has a UUID).

extract_slug_version_and_language(group_slug, identifier)

@spec extract_slug_version_and_language(String.t(), String.t() | nil) ::
  {String.t(), integer() | nil, String.t() | nil}

find_by_previous_url_slug(group_slug, language, url_slug)

@spec find_by_previous_url_slug(String.t(), String.t(), String.t()) ::
  {:ok, map()} | {:error, :not_found | :cache_miss}

Finds a post by a previous URL slug (for 301 redirects).

find_by_url_slug(group_slug, language, url_slug)

@spec find_by_url_slug(String.t(), String.t(), String.t()) ::
  {:ok, map()} | {:error, :not_found | :cache_miss}

Finds a post by URL slug from the database.

list_posts(group_slug, preferred_language \\ nil)

@spec list_posts(String.t(), String.t() | nil) :: [map()]

Lists posts for a given publishing group slug.

Queries the database directly via DBStorage. The optional second argument is accepted for API compatibility but unused.

list_posts_by_status(group_slug, status)

@spec list_posts_by_status(String.t(), String.t()) :: [map()]

Lists posts filtered by status (e.g. 'trashed', 'published').

list_raw_posts(group_slug, status \\ nil)

@spec list_raw_posts(String.t(), String.t() | nil) :: [struct()]

Lists raw DB post records for a group, optionally filtered by status.

list_times_on_date(group_slug, date)

@spec list_times_on_date(String.t(), Date.t() | String.t()) :: [Time.t()]

Lists time values for posts on a specific date.

read_post(group_slug, identifier, language \\ nil, version \\ nil)

@spec read_post(String.t(), String.t(), String.t() | nil, integer() | nil) ::
  {:ok, map()} | {:error, any()}

Reads an existing post.

For slug-mode groups, accepts an optional version parameter. If version is nil, reads the latest version.

Reads from the database.

read_post_by_uuid(post_uuid, language \\ nil, version \\ nil)

@spec read_post_by_uuid(String.t(), String.t() | nil, integer() | nil) ::
  {:ok, map()} | {:error, any()}

Reads a post by its database UUID.

Resolves the UUID to a group slug and post slug, then delegates to read_post/4. Invalid version/language params gracefully fall back to latest/primary.

restore_post(group_slug, post_uuid, opts \\ [])

@spec restore_post(String.t(), String.t(), keyword() | map()) ::
  {:ok, String.t()} | {:error, term()}

Restores a trashed post by UUID, clearing its trashed_at timestamp.

Regenerates the group cache and broadcasts the update. Returns {:ok, post_uuid} on success or {:error, reason} on failure.

trash_post(group_slug, post_uuid, opts \\ [])

@spec trash_post(String.t(), String.t(), keyword() | map()) ::
  {:ok, String.t()} | {:error, term()}

Soft-deletes a post by UUID (sets trashed_at timestamp).

Returns {:ok, post_uuid} on success or {:error, reason} on failure.

update_post(group_slug, post, params, opts \\ %{})

@spec update_post(String.t(), map(), map(), map() | keyword()) ::
  {:ok, map()} | {:error, any()}

Updates a post in the database.

update_version_defaults(version, params, post, legacy_promotions \\ %{})

@spec update_version_defaults(struct(), map(), map(), map()) :: :ok | {:error, term()}

Updates version.data with metadata like featured_image_uuid, description, seo_title, tags, etc.

Version is the source of truth for all post metadata beyond title and body. Merges new values into existing version.data, preserving keys not present in the update. The optional legacy_promotions map is merged in BEFORE the user updates so legacy content.data values fall through unchanged when the user didn't touch them — the promotion path that pairs with preserve_content_data's whitelist (see posts.ex do_update_post_in_db).