defmodule BerrypodWeb.SeoController do use BerrypodWeb, :controller alias Berrypod.{Pages, Products} alias BerrypodWeb.R def robots(conn, _params) do base = BerrypodWeb.Endpoint.url() content = """ User-agent: * Allow: / Disallow: /admin/ Disallow: /api/ Disallow: /users/ Disallow: /webhooks/ Disallow: /checkout/ Sitemap: #{base}/sitemap.xml """ conn |> put_resp_content_type("text/plain") |> send_resp(200, content) end def sitemap(conn, _params) do base = BerrypodWeb.Endpoint.url() products = Products.list_products_for_sitemap() categories = Products.list_categories() static_pages = [ {R.home(), "daily", "1.0", []}, {R.collection("all"), "daily", "0.9", []}, {R.about(), "monthly", "0.5", []}, {R.contact(), "monthly", "0.5", []}, {R.delivery(), "monthly", "0.5", []}, {R.privacy(), "monthly", "0.3", []}, {R.terms(), "monthly", "0.3", []} ] category_pages = Enum.map(categories, fn cat -> {R.collection(cat.slug), "daily", "0.8", []} end) product_pages = Enum.map(products, fn product -> images = product_image_entries(product, base) {R.product(product.slug), "weekly", "0.9", images} end) custom_pages = Pages.list_custom_pages() |> Enum.filter(& &1.published) |> Enum.map(fn page -> {"/#{page.slug}", "weekly", "0.6", []} end) all_pages = static_pages ++ category_pages ++ product_pages ++ custom_pages entries = Enum.map_join(all_pages, "\n", fn {path, changefreq, priority, images} -> image_tags = Enum.map_join(images, "\n", fn img -> """ #{xml_escape(img.url)} #{xml_escape(img.title)} """ |> String.trim_trailing() end) url_content = " #{xml_escape(base <> path)}\n" <> " #{changefreq}\n" <> " #{priority}" if image_tags == "" do " \n#{url_content}\n " else " \n#{url_content}\n#{image_tags}\n " end end) xml = """ #{entries} """ conn |> put_resp_content_type("application/xml") |> send_resp(200, xml) end defp product_image_entries(product, base_url) do product.images |> Enum.take(5) |> Enum.map(fn product_image -> image = product_image.image alt_text = product_image.alt_text || product.title url = "#{base_url}/image_cache/#{image.id}.webp" %{url: url, title: alt_text} end) end defp xml_escape(nil), do: "" defp xml_escape(text) when is_binary(text) do text |> String.replace("&", "&") |> String.replace("<", "<") |> String.replace(">", ">") |> String.replace("\"", """) |> String.replace("'", "'") end end