The microprints git dep now allows phoenix_live_view ~> 1.2, so the
app can take the CVE-2026-64941 fix (open redirect in
validate_local_url!/2, fixed in 1.2.9). No 1.1.x backport existed.
blogex test lock follows to 1.2.12 so the library is tested against
the version the app ships with. mix deps.get now reports zero
security advisories.
- Restore HTML link extraction in LinkValidator (removed in a83634d
under the false premise that post bodies are raw markdown; they
are HTML rendered by NimblePublisher at compile time). The missing
regex made extract_links/1 find zero links, silently disabling
compile-time validation.
- Support /blog/{blog_id}/tag/{tag} links: validate blog ID,
require non-empty tag (tags are user-defined, e.g. pi.dev).
- Fix invalid links in two posts: tag/Pi.dev -> tag/pi.dev,
2026-07-13-synthetic-tdd.md -> synthetic-tdd.
- Fix test warnings: use Plug.Test deprecation, unused import,
runtime-defined TestBlogValid module.
- Add regression tests for HTML extraction and tag page links.
External links in post bodies now open in a new tab and show a
box-with-arrow marker icon, so readers can tell at a glance which
links leave the site.
- blogex: new Blogex.ExternalLinks.rewrite/1 marks up anchors with
http(s) hrefs at compile time with target="_blank", rel="noopener"
and class="blogex-external" (idempotent, merges into existing
class/rel values, leaves relative, mailto: and #anchor links alone)
- blogex: Post.build/3 applies the rewrite, so every blog gets it
- app: CSS in .blogex-post-body draws the marker via a mask so it
inherits the link colour; empty ::after content stays invisible
to screen readers
- make test now also runs the blogex suite; it is currently red
with 3 pre-existing blog_integration_test failures caused by the
vacuous link validator (parked yak
link-validator-never-sees-compiled-html-...)
- Drop redundant :ok return in _validate_links/2 (blog.ex)
- Remove dead HTML link regex from extract_links/1 (body is raw markdown)
- Rename slug_slug_end/1 to slug_end/1
- Simplify parse_blog_link/1 to return {blog_id, slug}, removing
parse_query_fragment/1 and dead case branches
- all_posts/0 now excludes posts where date > today
- all_tags/0 computed at runtime from filtered posts
- posts_by_tag/1 and recent_posts/1 inherit date filtering
- Add unfiltered_posts/0 to Blog macro and FakeBlog
- Add all_posts_unfiltered/0 to Registry for dashboard use
Goal: have a personal blog, and try out another point in the 'modular
app design with elixir' space.
Designing OTP systems with elixir had some interesting ideas.