Current section
Files
Jump to
Current section
Files
lib/sitemap/builders/url.ex
defmodule Sitemap.Builders.Url do
alias Sitemap.Funcs
alias Sitemap.Config
import XmlBuilder
def to_xml(link, attrs \\ []) do
elms =
element(:url, Funcs.eraser([
element(:loc, Path.join(Config.get.host, link || "")),
element(:lastmod, Keyword.get_lazy(attrs, :lastmod, fn -> Funcs.iso8601 end)),
element(:expires, attrs[:expires]),
element(:changefreq, attrs[:changefreq]),
element(:priority, attrs[:priority]),
]))
elms = ifput attrs[:mobile], elms, &append_last(&1, mobile())
elms = ifput attrs[:geo], elms, &append_last(&1, geo(attrs[:geo]))
elms = ifput attrs[:news], elms, &append_last(&1, news(attrs[:news]))
elms = ifput attrs[:pagemap], elms, &append_last(&1, pagemap(attrs[:pagemap]))
elms = ifput attrs[:images], elms, &append_last(&1, images([attrs[:images]]))
elms = ifput attrs[:videos], elms, &append_last(&1, videos([attrs[:videos]]))
elms = ifput attrs[:alternates], elms, &append_last(&1, alternates([attrs[:alternates]]))
elms
end
defp ifput(bool, elms, fun) do
if bool do
fun.(elms)
else
elms
end
end
defp append_last(elements, element) do
combine = elem(elements, 2) ++ [element]
elements
|> Tuple.delete_at(2)
|> Tuple.append(combine)
end
defp news(data) do
element(:"news:news", Funcs.eraser([
element(:"news:publication", Funcs.eraser([
element(:"news:name", data[:publication_name]),
element(:"news:language", data[:publication_language]),
])),
element(:"news:title", data[:title]),
element(:"news:access", data[:access]),
element(:"news:genres", data[:genres]),
element(:"news:keywords", data[:keywords]),
element(:"news:stock_tickers", data[:stock_tickers]),
element(:"news:publication_date", data[:publication_date]),
]))
end
defp images(list, elements \\ [])
defp images([], elements), do: elements
defp images([data|tail], elements) do
elm =
element(:"image:image", Funcs.eraser([
element(:"image:loc", data[:loc]),
(unless is_nil(data[:title]), do: element(:"image:title", data[:title])),
(unless is_nil(data[:license]), do: element(:"image:license", data[:license])),
(unless is_nil(data[:caption]), do: element(:"image:caption", data[:caption])),
(unless is_nil(data[:geo_location]), do: element(:"image:geo_location", data[:geo_location])),
]))
images(tail, elements ++ [elm])
end
defp videos(list, elements \\ [])
defp videos([], elements), do: elements
defp videos([data|tail], elements) do
elm =
element(:"video:video", Funcs.eraser([
element(:"video:title", data[:title]),
element(:"video:description", data[:description]),
(if data[:player_loc] do
attrs = %{allow_embed: Funcs.yes_no(data[:allow_embed])}
attrs = ifput data[:autoplay], attrs, &Map.put(&1, :autoplay, Funcs.autoplay(data[:autoplay]))
element(:"video:player_loc", attrs, data[:player_loc])
end),
element(:"video:content_loc", data[:content_loc]),
element(:"video:thumbnail_loc", data[:thumbnail_loc]),
element(:"video:duration", data[:duration]),
(unless is_nil(data[:gallery_loc]), do: element(:"video:gallery_loc", %{title: data[:gallery_title]}, data[:gallery_loc])),
(unless is_nil(data[:rating]), do: element(:"video:rating", data[:rating])),
(unless is_nil(data[:view_count]), do: element(:"video:view_count", data[:view_count])),
(unless is_nil(data[:expiration_date]), do: element(:"video:expiration_date", data[:expiration_date])), # TODO: gonna be convinient
(unless is_nil(data[:publication_date]), do: element(:"video:publication_date", data[:publication_date])), # TODO: gonna be convinient
(unless is_nil(data[:tags]), do: Enum.map(data[:tags] || [], &(element(:"video:tag", &1)))),
(unless is_nil(data[:tag]), do: element(:"video:tag", data[:tag])),
(unless is_nil(data[:category]), do: element(:"video:category", data[:category])),
(unless is_nil(data[:family_friendly]), do: element(:"video:family_friendly", Funcs.yes_no(data[:family_friendly]))),
(unless is_nil(data[:restriction]) do
attrs = %{relationship: Funcs.allow_deny(data[:relationship])}
element(:"video:restriction", attrs, data[:restriction])
end),
(unless is_nil(data[:uploader]) do
attrs = %{}
attrs = ifput data[:uploader_info], attrs, &Map.put(&1, :info, data[:uploader_info])
element(:"video:uploader", attrs, data[:uploader])
end),
(unless is_nil(data[:price]), do: element(:"video:price", video_price_attrs(data), data[:price])),
(unless is_nil(data[:live]), do: element(:"video:live", Funcs.yes_no(data[:live]))),
(unless is_nil(data[:requires_subscription]), do: element(:"video:requires_subscription", Funcs.yes_no(data[:requires_subscription]))),
]))
videos(tail, elements ++ [elm])
end
defp video_price_attrs(data) do
attrs = %{}
attrs = Map.put attrs, :currency, data[:price_currency]
attrs = ifput data[:price_type], attrs, &Map.put(&1, :type, data[:price_type])
attrs = ifput data[:price_type], attrs, &Map.put(&1, :resolution, data[:price_resolution])
attrs
end
defp alternates(list, elements \\ [])
defp alternates([], elements), do: elements
defp alternates([data|tail], elements) do
rel = if data[:nofollow], do: "alternate nofollow", else: "alternate"
attrs = %{rel: rel, href: data[:href]}
attrs = Map.put attrs, :hreflang, data[:lang]
attrs = Map.put attrs, :media, data[:media]
alternates(tail, elements ++ [element(:"xhtml:link", attrs)])
end
defp geo(data) do
element(:"geo:geo", [
element(:"geo:format", data[:format])
])
end
defp mobile do
element(:"mobile:mobile")
end
defp pagemap(data) do
element(:PageMap, Enum.map(data[:dataobjects] || [], fn(obj) ->
element(:DataObject, %{type: obj[:type], id: obj[:id]}, Enum.map(obj[:attributes] || [], fn(attr) ->
element(:Attribute, %{name: attr[:name]}, attr[:value])
end))
end))
end
end