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.
63 lines
1.6 KiB
Elixir
63 lines
1.6 KiB
Elixir
defmodule Blogex.SEO do
|
|
@moduledoc """
|
|
SEO helpers for generating meta tags and sitemaps.
|
|
"""
|
|
|
|
@doc """
|
|
Returns a map of meta tag attributes for a post.
|
|
Useful for setting OpenGraph and Twitter card tags in your layout.
|
|
|
|
<meta property="og:title" content={@meta.og_title} />
|
|
"""
|
|
def meta_tags(post, base_url, blog_module) do
|
|
url = "#{base_url}#{blog_module.base_path()}/#{post.id}"
|
|
|
|
%{
|
|
title: post.title,
|
|
description: post.description,
|
|
og_title: post.title,
|
|
og_description: post.description,
|
|
og_type: "article",
|
|
og_url: url,
|
|
article_published_time: Date.to_iso8601(post.date),
|
|
article_author: post.author,
|
|
article_tags: post.tags,
|
|
twitter_card: "summary_large_image"
|
|
}
|
|
end
|
|
|
|
@doc """
|
|
Generates a sitemap.xml string for the given blog modules.
|
|
|
|
xml = Blogex.SEO.sitemap([MyApp.EngineeringBlog, MyApp.ReleaseNotes], "https://myapp.com")
|
|
"""
|
|
def sitemap(blog_modules, base_url) when is_list(blog_modules) do
|
|
urls =
|
|
blog_modules
|
|
|> Enum.flat_map(fn mod ->
|
|
mod.all_posts()
|
|
|> Enum.map(fn post ->
|
|
url = "#{base_url}#{mod.base_path()}/#{post.id}"
|
|
lastmod = Date.to_iso8601(post.date)
|
|
|
|
"""
|
|
<url>
|
|
<loc>#{url}</loc>
|
|
<lastmod>#{lastmod}</lastmod>
|
|
<changefreq>monthly</changefreq>
|
|
<priority>0.7</priority>
|
|
</url>
|
|
"""
|
|
end)
|
|
end)
|
|
|> Enum.join()
|
|
|
|
"""
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
|
#{urls}</urlset>
|
|
"""
|
|
|> String.trim()
|
|
end
|
|
end
|