Packages
phoenix_kit
1.7.64
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/modules/publishing/web/controller/routing.ex
defmodule PhoenixKit.Modules.Publishing.Web.Controller.Routing do
@moduledoc """
URL path parsing and routing helpers for the publishing controller.
Handles segment building from params and path pattern matching
to determine the type of request (listing, slug post, timestamp post, etc.).
"""
# ============================================================================
# Segment Building
# ============================================================================
@doc """
Builds path segments from route params.
Returns a list of path segments starting with the group slug,
followed by any additional path segments.
"""
def build_segments(%{"group" => group} = params) when is_binary(group) do
case Map.get(params, "path") do
nil -> [group]
path when is_list(path) -> [group | path]
path when is_binary(path) -> [group, path]
_ -> [group]
end
end
def build_segments(_), do: []
# ============================================================================
# Path Parsing
# ============================================================================
@doc """
Parses path segments to determine the request type.
Returns one of:
- `{:listing, group_slug}`
- `{:slug_post, group_slug, post_slug}`
- `{:timestamp_post, group_slug, date, time}`
- `{:date_only_post, group_slug, date}`
- `{:versioned_post, group_slug, post_slug, version}`
- `{:error, reason}`
"""
def parse_path([]), do: {:error, :invalid_path}
def parse_path([group_slug]), do: {:listing, group_slug}
def parse_path([group_slug, segment1, segment2]) do
# Check if this is timestamp mode: segment1 matches date, segment2 matches time
if date?(segment1) and time?(segment2) do
{:timestamp_post, group_slug, segment1, segment2}
else
# Invalid format
{:error, :invalid_path}
end
end
# Version-specific URL: /group/post-slug/v/2
def parse_path([group_slug, post_slug, "v", version_str]) do
case Integer.parse(version_str) do
{version, ""} when version > 0 ->
{:versioned_post, group_slug, post_slug, version}
_ ->
{:error, :invalid_version}
end
end
def parse_path([group_slug, segment]) do
# Check if segment is a date (for date-only timestamp URLs)
# If it's a date, treat as date-only timestamp post
# Otherwise, treat as slug mode post
if date?(segment) do
{:date_only_post, group_slug, segment}
else
{:slug_post, group_slug, segment}
end
end
def parse_path(_), do: {:error, :invalid_path}
# ============================================================================
# Date/Time Validation
# ============================================================================
@doc """
Validates a date string (YYYY-MM-DD format).
"""
def date?(str) when is_binary(str) do
String.match?(str, ~r/^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/)
end
def date?(_), do: false
@doc """
Validates a time string (HH:MM 24-hour format).
"""
def time?(str) when is_binary(str) do
String.match?(str, ~r/^([01]\d|2[0-3]):[0-5]\d$/)
end
def time?(_), do: false
end