Skip to content

Commit 987be5a

Browse files
ddonclaude
andcommitted
Fix publishing bugs and clean up stale filesystem references
Fix slug conflict clearing passing wrong slug to DB cleanup, fix ngettext interpolation showing literal %{count} in migration modal, rename find_dialect_for_base_in_files to find_dialect_for_base_in_languages, update stale comments and user-facing strings referencing filesystem storage. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 028a809 commit 987be5a

13 files changed

Lines changed: 42 additions & 42 deletions

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
## 1.7.63 - 2026-03-06
2-
- Remove filesystem storage mode from publishing module — `storage_mode()` now always returns `:db`, remove ~780 lines of dead FS code, migration gate, and "Database migration required" banner
2+
- Remove filesystem storage from publishing module — delete Storage, DualWrite, and all storage/* submodules (~7k lines removed)
3+
- Add LanguageHelpers and SlugHelpers as standalone modules, simplify to DB-only throughout
4+
- Fix slug conflict clearing bug: `clear_url_slugs_for_conflicts` passed wrong slug to DB cleanup
5+
- Fix ngettext interpolation in primary language migration modal (literal `%{count}` in UI)
6+
- Clean up stale filesystem references in comments, docs, and user-facing strings
37
- Fix V77/V78 migration crashes when UUID columns are missing (tables created after V56 ran)
48
- Simplify V77/V78 migrations — remove over-engineered column detection, rely on idempotent patterns
59
- Fix email tracking bug: `handle_delivery_result` used `get_log!` (raises) in a nil-matching branch; add `get_log/1` non-bang wrapper and remove unused public functions

lib/mix/tasks/phoenix_kit.migrate_blogging_to_publishing.ex

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
defmodule Mix.Tasks.PhoenixKit.MigrateBloggingToPublishing do
2-
@shortdoc "Migrates blogging module to publishing (storage path and settings)"
2+
@shortdoc "Migrates blogging module to publishing (settings)"
33
@moduledoc """
44
Migrates the PhoenixKit blogging module to the new publishing module.
55
66
## What this task does
77
8-
1. Renames `priv/blogging` directory to `priv/publishing` (if it exists)
9-
2. Migrates settings keys from legacy names to new names:
8+
Migrates settings keys from legacy names to new names:
109
- `blogging_enabled` → `publishing_enabled`
1110
- `blogging_blogs` → `publishing_groups`
12-
- `blogging_file_cache_enabled` → `publishing_file_cache_enabled`
1311
- `blogging_memory_cache_enabled` → `publishing_memory_cache_enabled`
1412
- `blogging_render_cache_enabled` → `publishing_render_cache_enabled`
1513
- `blogging_render_cache_enabled_*` → `publishing_render_cache_enabled_*`

lib/modules/publishing/pubsub.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ defmodule PhoenixKit.Modules.Publishing.PubSub do
372372
end
373373

374374
@doc """
375-
Broadcasts that the cache state has changed (file regenerated, memory loaded, etc).
375+
Broadcasts that the cache state has changed (cache regenerated, memory loaded, etc).
376376
"""
377377
def broadcast_cache_changed(group_slug) do
378378
Manager.broadcast(cache_topic(group_slug), {:cache_changed, group_slug})

lib/modules/publishing/slug_helpers.ex

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ defmodule PhoenixKit.Modules.Publishing.SlugHelpers do
9595
case ListingCache.read(group_slug) do
9696
{:ok, posts} ->
9797
conflicts = find_conflicting_url_slugs(posts, directory_slug)
98-
clear_url_slugs_for_conflicts(group_slug, conflicts)
98+
clear_url_slugs_for_conflicts(group_slug, directory_slug, conflicts)
9999
log_cleared_conflicts(conflicts, directory_slug)
100100
conflicts
101101

@@ -212,10 +212,9 @@ defmodule PhoenixKit.Modules.Publishing.SlugHelpers do
212212
end)
213213
end
214214

215-
defp clear_url_slugs_for_conflicts(group_slug, conflicts) do
215+
defp clear_url_slugs_for_conflicts(group_slug, directory_slug, conflicts) do
216216
Enum.each(conflicts, fn {post_slug, _language} ->
217-
# Clear via DB
218-
DBStorage.clear_url_slug_from_post(group_slug, post_slug, post_slug)
217+
DBStorage.clear_url_slug_from_post(group_slug, post_slug, directory_slug)
219218
end)
220219
end
221220

lib/modules/publishing/web/controller/language.ex

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -150,31 +150,31 @@ defmodule PhoenixKit.Modules.Publishing.Web.Controller.Language do
150150
# ============================================================================
151151

152152
@doc """
153-
Resolves a language code to an actual file language.
153+
Resolves a language code to an actual content language.
154154
Handles base codes by finding a matching dialect in available languages.
155155
"""
156156
def resolve_language_for_post(language, available_languages) do
157157
cond do
158-
# Direct match - language exactly matches an available file
158+
# Direct match - language exactly matches an available language
159159
language in available_languages ->
160160
language
161161

162162
# Base code - try to find a dialect that matches
163163
base_code?(language) ->
164-
find_dialect_for_base_in_files(language, available_languages) ||
164+
find_dialect_for_base_in_languages(language, available_languages) ||
165165
DialectMapper.base_to_dialect(language)
166166

167167
# Full dialect code not found - try base code match as fallback
168168
true ->
169169
base = DialectMapper.extract_base(language)
170-
find_dialect_for_base_in_files(base, available_languages) || language
170+
find_dialect_for_base_in_languages(base, available_languages) || language
171171
end
172172
end
173173

174174
@doc """
175-
Find a dialect in available files that matches the given base code.
175+
Find a dialect in available languages that matches the given base code.
176176
"""
177-
def find_dialect_for_base_in_files(base_code, available_languages) do
177+
def find_dialect_for_base_in_languages(base_code, available_languages) do
178178
base_lower = String.downcase(base_code)
179179

180180
Enum.find(available_languages, fn lang ->

lib/modules/publishing/web/controller/listing.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,12 +234,12 @@ defmodule PhoenixKit.Modules.Publishing.Web.Controller.Listing do
234234

235235
# Base code - find a dialect that matches
236236
Language.base_code?(language) ->
237-
Language.find_dialect_for_base_in_files(language, available_languages)
237+
Language.find_dialect_for_base_in_languages(language, available_languages)
238238

239239
# Full dialect not found - try base code match
240240
true ->
241241
base = DialectMapper.extract_base(language)
242-
Language.find_dialect_for_base_in_files(base, available_languages)
242+
Language.find_dialect_for_base_in_languages(base, available_languages)
243243
end
244244
end
245245

lib/modules/publishing/web/controller/translations.ex

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,12 @@ defmodule PhoenixKit.Modules.Publishing.Web.Controller.Translations do
7575
end
7676

7777
# Check if a specific enabled language has published content in the group
78-
# ONLY checks for EXACT file matches - no base code fallback
79-
# This ensures only languages with actual files show in the public switcher
78+
# ONLY checks for EXACT matches - no base code fallback
79+
# This ensures only languages with actual content show in the public switcher
8080
# Uses passed posts to avoid redundant list_posts calls
8181
defp has_published_content_for_language?(posts, language) do
8282
Enum.any?(posts, fn post ->
83-
# Check if there's a published file for this EXACT language only
83+
# Check if there's published content for this EXACT language only
8484
# Use preloaded language_statuses map
8585
language in (post.available_languages || []) and
8686
Map.get(post.language_statuses, language) == "published"
@@ -249,30 +249,30 @@ defmodule PhoenixKit.Modules.Publishing.Web.Controller.Translations do
249249
defp normalize_languages([], current_language), do: [current_language]
250250
defp normalize_languages(languages, _current_language) when is_list(languages), do: languages
251251

252-
# Strict check for public display - only shows files that are:
252+
# Strict check for public display - only shows languages that are:
253253
# 1. Directly in the enabled languages list, OR
254254
# 2. Base code files where any dialect of that base is enabled
255255
# This prevents showing en-US, en-GB etc when only en-CA is enabled
256256
defp language_enabled_for_public?(language, enabled_languages) do
257257
cond do
258-
# Direct match - file code exactly matches an enabled language
258+
# Direct match - language code exactly matches an enabled language
259259
language in enabled_languages ->
260260
true
261261

262-
# Base code file (e.g., "en") - show if any dialect is enabled
262+
# Base code (e.g., "en") - show if any dialect is enabled
263263
Language.base_code?(language) ->
264264
Enum.any?(enabled_languages, fn enabled_lang ->
265265
DialectMapper.extract_base(enabled_lang) == language
266266
end)
267267

268-
# Dialect file (e.g., "en-US") not directly enabled - DON'T show
268+
# Dialect (e.g., "en-US") not directly enabled - DON'T show
269269
# This is the key difference from language_enabled?
270270
true ->
271271
false
272272
end
273273
end
274274

275-
# Checks if the exact language file exists and is published
275+
# Checks if the exact language translation exists and is published
276276
# Uses preloaded language_statuses map to avoid redundant DB reads
277277
defp translation_published_exact?(_group_slug, post, language) do
278278
language in (post.available_languages || []) and

lib/modules/publishing/web/listing.html.heex

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,8 @@
507507
{ngettext(
508508
"This will update the primary language setting for %{count} post in this publishing group.",
509509
"This will update the primary language setting for %{count} posts in this publishing group.",
510-
total_needing
510+
total_needing,
511+
count: total_needing
511512
)}
512513
</p>
513514

@@ -556,7 +557,9 @@
556557
phx-disable-with={gettext("Updating...")}
557558
>
558559
<.icon name="hero-arrow-path" class="w-4 h-4" />
559-
{ngettext("Update %{count} Post", "Update %{count} Posts", total_needing)}
560+
{ngettext("Update %{count} Post", "Update %{count} Posts", total_needing,
561+
count: total_needing
562+
)}
560563
</button>
561564
</div>
562565
</div>

lib/modules/publishing/web/new.html.heex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
/>
5454
<div class="space-y-1">
5555
<p class="text-xs text-base-content/60">
56-
{gettext("Used for the URL and the directory where files are stored.")}
56+
{gettext("Used for the URL and as the unique identifier for this group.")}
5757
</p>
5858
<p class="text-xs font-medium text-base-content/70">
5959
<span class="font-semibold">{gettext("Format")}:</span>

lib/modules/publishing/web/settings.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ defmodule PhoenixKit.Modules.Publishing.Web.Settings do
7676
)}
7777

7878
{:error, :not_found} ->
79-
# Group directory doesn't exist, just remove from config
79+
# Group not found in DB, just remove from config
8080
case Publishing.remove_group(slug) do
8181
{:ok, _} ->
8282
# The `Publishing.remove_group` call handles the broadcast. This

0 commit comments

Comments
 (0)