Packages

Very simple sitemap generator for Elixir inspired by sitemap_generator.

Current section

Files

Jump to
plain_sitemap lib plain_sitemap.ex
Raw

lib/plain_sitemap.ex

defmodule PlainSitemap do
use Application
def start(_type, _args) do
PlainSitemap.Supervisor.start_link
end
defmacro __using__(opts) do
quote location: :keep do
unquote(config(opts))
import unquote(__MODULE__), only: [urlset: 1, add: 1, add: 2]
import XmlBuilder
end
end
defmacro urlset([do: block]) do
quote location: :keep do
@default_output_dir "priv/static"
@output_file_name "sitemap.xml.gz"
def render do
PlainSitemap.Generator.flush
unquote(block)
current_datetime = Timex.DateTime.now
doc(:urlset, unquote(__MODULE__).urlset_attributes, Enum.map(PlainSitemap.Generator.urlset, fn({path, opts}) ->
element(:url, %{}, [
element(:loc, "#{opts[:host] || @default_host}#{path}"),
element(:lastmod, (opts[:lastmod] || current_datetime) |> unquote(__MODULE__).timezone_string),
element(:changefreq, opts[:changefreq] || "daily"),
element(:priority, opts[:priority] || 1.0)
])
end))
end
def refresh do
{:ok, _} = Application.ensure_all_started(@app)
generator = (Application.get_env(:plain_sitemap, :generator) || raise "sitemap generator is not defined. see README.md")
path = Application.app_dir(@app) |> Path.join(Application.get_env(:plain_sitemap, :output_dir, @default_output_dir)) |> Path.join(@output_file_name)
{:ok, file} = File.open path, [:utf8, :write, :compressed]
IO.write file, generator.render
File.close file
end
end
end
defmacro add(path, opts \\ []) do
quote location: :keep do
PlainSitemap.Generator.add(unquote(path), unquote(opts))
end
end
def urlset_attributes do
%{
:"xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
:"xsi:schemaLocation" => "http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd",
:"xmlns" => "http://www.sitemaps.org/schemas/sitemap/0.9",
:"xmlns:image" => "http://www.google.com/schemas/sitemap-image/1.1",
:"xmlns:video" => "http://www.google.com/schemas/sitemap-video/1.1",
:"xmlns:geo" => "http://www.google.com/geo/schemas/sitemap/1.0",
:"xmlns:news" => "http://www.google.com/schemas/sitemap-news/0.9",
:"xmlns:mobile" => "http://www.google.com/schemas/sitemap-mobile/1.0",
:"xmlns:pagemap" => "http://www.google.com/schemas/sitemap-pagemap/1.0",
:"xmlns:xhtml" => "http://www.w3.org/1999/xhtml"
}
end
def timezone_string(%Ecto.DateTime{} = datetime) do
{:ok, dump} = Ecto.DateTime.dump(datetime)
Timex.DateTime.from(dump)
|> timezone_string
end
def timezone_string(%Timex.DateTime{} = datetime) do
datetime |> Timex.format!("%FT%T%:z", :strftime)
end
defp config(opts) do
quote do
@app unquote(opts)[:app] || raise ":app must be given."
@default_host unquote(opts)[:default_host] || raise ":default_host must be given."
end
end
end