Add blogging module enhancements: video components, metadata extraction, and code quality improvements - #180
Merged
Merged
Conversation
- add `PhoenixKitWeb.Components.Blogging.Video`, wire it into the PHK renderer/inline markdown flow, and document usage in guides - improve slug-mode storage to handle legacy posts without title/status and derive titles from content safely - teach metadata title extraction to skip inline components so hero/video blocks don’t hide headings - add missing Hammer config to the parent app so rate limiting boots in dev/test
- teach `Metadata.extract_title_from_content/1` to handle multi-line self-closing PHK components so opening tags like `<Video … />` no longer block headings from being detected - ensure the title scanner decrements its component depth when it hits a trailing `/>`, allowing the subsequent Markdown `# Heading` to be promoted to the metadata title
- skip multi-line self-closing PHK components when scanning markdown so headings after blocks like <Video .../> are still detected - add component-aware fallbacks: pull text from <Headline>...</Headline>, <Title>...</Title>, or Hero’s title attribute when no markdown heading exists - sanitize captured component text before storing in metadata
- normalize the translation list so we always include the current language, but only show languages that are enabled and have a published translation file - load each translation’s metadata to check status before rendering a badge/link, preventing drafts from appearing on the public post header
- extend blog metadata/frontmatter to store `featured_image_id`, propagate it through storage updates (slug + timestamp modes), and expose helper to resolve a public URL - update the LiveView editor: * add a featured-image ID field with preview/validation, guide authors to Media Manager * include the new field in form normalization, post creation/update payloads, and metadata defaults so each translation can track its own image * fix the “View Public” button to build URLs with the current translation’s language, handling initial load/new translation states - hide unpublished translations on the public language switcher by checking each translation’s `.phk` metadata before rendering badges - show featured image thumbnails on the public blog index cards via the new helper
Fix architectural issues identified in code review: 1. Configuration Pattern Fix - Change blogging.ex line 367 to use PhoenixKit.Config.get instead of Application.get_env - Aligns with project-wide configuration management pattern - Maintains identical interface (non-breaking change) 2. Test Configuration Structure - Add config/test.exs with proper test environment settings - Configure test mailer with Swoosh.Adapters.Test - Set test-friendly Hammer rate limiting configuration - Update config.exs to import environment-specific configs 3. Documentation Updates - Mark FakeSettings as "Future Implementation" in blogging README - Document correct config/test.exs pattern (not runtime Application.put_env) - Clarify test status and future implementation approach - Update troubleshooting section with correct configuration examples All changes follow standard Elixir/Phoenix configuration practices.
Address code quality improvements identified by Credo --strict: 1. Logger Metadata Warning - Add :error metadata key to Logger config to support error logging in preview.ex 2. Nested Module Aliases (Software Design) - Add module aliases to blogging/renderer.ex for PageBuilder, Image, Video, and Safe - Add module aliases to components/blogging/hero.ex and page.ex for Renderer - Replace long-form module references with aliased names - Sort aliases alphabetically per Elixir conventions 3. Code Readability - Rename is_pure_phk_content? to pure_phk_content? (remove 'is' prefix per Elixir style) - Replace explicit try-rescue with implicit rescue in storage.ex signed_file_url/2 4. Refactoring Opportunities - Replace Enum.map |> Enum.join with Enum.map_join in page_builder/renderer.ex - Combine double Enum.filter into single filter with combined predicate in blog_controller.ex - Replace cond with if/else in video.ex extract_standard_id/1 (only 2 conditions) All changes improve code readability and performance while maintaining identical functionality. Credo analysis: 4754 mods/funs, found no issues.
Address all code quality issues from CI/CD pipeline checks: ## Credo Fixes (Upstream Code) - Replace explicit try-rescue with implicit rescue in repo_detection.ex:add_repo_config_to_files/2 - Remove unnecessary parentheses from config.ex:get_parent_app_fallback/0 - Both fixes improve code readability per Elixir style guide ## Dialyzer Fixes (Blogging Module) ### blogging/renderer.ex - Remove unreachable is_binary guards in Image and Video rendering - Simplify component rendering: always returns Phoenix.LiveView.Rendered struct - Remove unreachable normalize_markdown/1 fallback clause (input always binary) ### components/blogging/video.ex - Remove unreachable catch-all clauses in parse_uri/1 and classify_host/1 - Input types guaranteed by with statement guards ### controllers/blog_controller.ex - Remove nil clause from normalize_languages/2 - Dialyzer proves available_languages is always a list, never nil ### live/modules/blogging/context/metadata.ex - Fix Regex.run argument order: (regex, string, opts) not (string, regex, opts) - Add missing featured_image_id field to metadata type spec - Fixes invalid_contract and call errors ### live/modules/blogging/editor.ex - Remove unused current_language/1 function - Eliminates production compilation warning with --warnings-as-errors ## Verification - Credo: 4751 mods/funs, 0 issues ✅ - Production compile: No warnings with --warnings-as-errors ✅ - All changes maintain identical runtime behavior
**Dialyzer Fixes:** 1. **basic_configuration.ex** - Fixed Igniter.Project.Config.configure_new calls - Changed config_path from atom to list format - `:parent_app_name` → `[:parent_app_name]` - `:parent_module` → `[:parent_module]` - Matches Igniter API signature: `configure_new(igniter, file_path, app_name, config_path_list, value)` 2. **editor.ex** - Removed unreachable guard in post.language check - Dialyzer proved `post.language` is always binary (never nil) - Removed unnecessary `language = post.language || editor_language(socket.assigns)` - Changed `build_public_url(post, language)` → `build_public_url(post, post.language)` - Guard `when binary() === nil` can never succeed **Cascading Effect:** - Installing/updating tasks showed "unused function" warnings due to type error blocking pipeline analysis - These should resolve now that BasicConfiguration.add_basic_config/1 has correct return type All fixes maintain identical runtime behavior while satisfying static type analysis.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR enhances the PhoenixKit blogging module with new features, improved metadata handling, and architectural fixes addressing code review feedback.
New Features
YouTube Video Component
Featured Images & Translation Support
Improvements
Metadata Extraction Hardening
Configuration Architecture Fixes
Application.get_env/3withPhoenixKit.Config.get/2in blogging moduleconfig/test.exsfor proper test environment configurationCode Quality (Credo Fixes)
:errormetadata key to Logger configurationis_pure_phk_content?topure_phk_content?(Elixir style guide)try-rescuewith implicitrescuefor cleaner codemap |> join→map_join(4 occurrences)Enum.filterinto single filter for better performancecondwithif/elseCredo Result: 4754 mods/funs analyzed, 0 issues ✅
Files Changed
New Features
lib/phoenix_kit_web/components/blogging/video.exConfiguration
lib/phoenix_kit_web/live/modules/blogging/blogging.ex(Config pattern fix)config/test.exs(new file)config/config.exs(test config import + Logger metadata)Documentation
lib/phoenix_kit_web/live/modules/blogging/README.md(test configuration docs)Code Quality
lib/phoenix_kit/blogging/renderer.exlib/phoenix_kit/storage.exlib/phoenix_kit_web/components/blogging/hero.exlib/phoenix_kit_web/components/blogging/page.exlib/phoenix_kit_web/controllers/blog_controller.exlib/phoenix_kit_web/live/modules/blogging/context/page_builder/renderer.exTesting
mix formatMigration Notes
For existing installations:
Application.get_envtoPhoenixKit.Config.getis non-breaking (same interface)config/test.exsis optional but recommended for test environmentsChecklist
mix formatThis PR message tells a cohesive story of the improvements while providing clear sections for reviewers to understand the scope, impact, and quality of the
changes.