Packages

phoenix_kit

1.7.21
1.7.213 1.7.212 1.7.211 1.7.210 1.7.209 1.7.208 1.7.207 1.7.206 1.7.205 1.7.204 1.7.203 1.7.202 1.7.201 1.7.200 1.7.199 1.7.198 1.7.197 1.7.196 1.7.194 1.7.193 1.7.192 1.7.191 1.7.190 1.7.189 1.7.187 1.7.186 1.7.185 1.7.184 1.7.183 1.7.182 1.7.181 1.7.180 1.7.179 1.7.178 1.7.177 1.7.176 1.7.175 1.7.174 1.7.173 1.7.172 1.7.171 1.7.170 1.7.169 1.7.168 1.7.167 1.7.166 1.7.165 1.7.164 1.7.162 1.7.161 1.7.160 1.7.159 1.7.157 1.7.156 1.7.155 1.7.154 1.7.153 1.7.152 1.7.151 1.7.150 1.7.149 1.7.146 1.7.145 1.7.144 1.7.143 1.7.138 1.7.133 1.7.132 1.7.131 1.7.130 1.7.128 1.7.126 1.7.125 1.7.121 1.7.120 1.7.119 1.7.118 1.7.117 1.7.116 1.7.115 1.7.114 1.7.113 1.7.112 1.7.111 1.7.110 1.7.109 1.7.108 1.7.107 1.7.106 1.7.105 1.7.104 1.7.103 1.7.102 1.7.101 1.7.100 1.7.99 1.7.98 1.7.97 1.7.96 1.7.95 1.7.94 1.7.93 1.7.92 1.7.91 1.7.90 1.7.89 1.7.88 1.7.87 1.7.86 1.7.85 1.7.84 1.7.83 1.7.82 1.7.81 1.7.80 1.7.79 1.7.78 1.7.77 1.7.76 1.7.75 1.7.74 1.7.71 1.7.70 1.7.69 1.7.66 1.7.65 1.7.64 1.7.63 1.7.62 1.7.61 1.7.59 1.7.58 1.7.57 1.7.56 1.7.55 1.7.54 1.7.53 1.7.52 1.7.51 1.7.49 1.7.44 1.7.43 1.7.42 1.7.41 1.7.39 1.7.38 1.7.37 1.7.36 1.7.34 1.7.33 1.7.31 1.7.30 1.7.29 1.7.28 1.7.27 1.7.26 1.7.25 1.7.24 1.7.23 1.7.22 1.7.21 1.7.20 1.7.19 1.7.18 1.7.17 1.7.16 1.7.15 1.7.14 1.7.13 1.7.12 1.7.11 1.7.10 1.7.9 1.7.8 1.7.7 1.7.6 1.7.5 1.7.4 1.7.3 1.7.2 1.7.1 1.7.0 1.6.20 1.6.19 1.6.18 1.6.17 1.6.16 1.6.15 1.6.14 1.6.13 1.6.12 1.6.11 1.6.10 1.6.9 1.6.8 1.6.7 1.6.6 1.6.5 1.6.4 1.6.3 1.5.2 1.5.1 1.5.0 1.4.9 1.4.8 1.4.7 1.4.6 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.3.2 1.3.1 1.3.0 1.2.10 1.2.9 1.2.8 1.2.7 1.2.5 1.2.4 1.2.2 1.2.1 1.2.0 1.1.0 1.0.0

A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more

Current section

Files

Jump to
phoenix_kit priv static assets sitemap-cards.xsl
Raw

priv/static/assets/sitemap-cards.xsl

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:sitemap="http://www.sitemaps.org/schemas/sitemap/0.9"
exclude-result-prefixes="sitemap">
<xsl:output method="html" indent="yes" encoding="UTF-8"/>
<xsl:template match="/">
<html>
<head>
<title>Site Map</title>
<style>
body { font-family: -apple-system, BlinkMacSystemFont, sans-serif; margin: 2rem; background: #f8fafc; color: #1e293b; }
h1 { font-size: 2rem; text-align: center; margin-bottom: 0.5rem; }
.subtitle { text-align: center; color: #64748b; margin-bottom: 2rem; }
.stats { display: flex; justify-content: center; gap: 2rem; margin-bottom: 2rem; }
.stat { background: white; padding: 1rem 1.5rem; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); text-align: center; }
.stat-value { font-size: 1.5rem; font-weight: 700; color: #3b82f6; }
.stat-label { font-size: 12px; color: #64748b; text-transform: uppercase; }
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: 1.5rem; }
.card { background: white; border-radius: 12px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); overflow: hidden; }
.card-header { padding: 1rem 1.25rem; border-bottom: 1px solid #e2e8f0; display: flex; justify-content: space-between; align-items: center; }
.card-title { font-weight: 600; }
.card-count { background: #f1f5f9; padding: 4px 12px; border-radius: 999px; font-size: 12px; color: #64748b; }
.url-list { list-style: none; padding: 0; margin: 0; max-height: 400px; overflow-y: auto; }
.url-item { padding: 12px 1.25rem; border-bottom: 1px solid #e2e8f0; }
.url-item:last-child { border-bottom: none; }
.url-item:hover { background: #f8fafc; }
a { color: #3b82f6; text-decoration: none; font-size: 14px; word-break: break-all; }
a:hover { text-decoration: underline; }
.meta { font-size: 12px; color: #94a3b8; margin-top: 4px; }
@media (prefers-color-scheme: dark) {
body { background: #0f172a; color: #f1f5f9; }
.stat, .card { background: #1e293b; }
.card-header, .url-item { border-color: #334155; }
.url-item:hover { background: #334155; }
.card-count { background: #334155; color: #94a3b8; }
}
</style>
</head>
<body>
<h1>Site Map</h1>
<p class="subtitle">Browse all pages on this website</p>
<div class="stats">
<div class="stat">
<div class="stat-value"><xsl:value-of select="count(sitemap:urlset/sitemap:url)"/></div>
<div class="stat-label">Total URLs</div>
</div>
</div>
<div class="cards">
<!-- Main pages (homepage) -->
<xsl:variable name="main" select="sitemap:urlset/sitemap:url[
string-length(substring-after(substring-after(sitemap:loc, '://'), '/')) &lt; 2
]"/>
<xsl:if test="count($main) &gt; 0">
<div class="card">
<div class="card-header">
<span class="card-title">Main</span>
<span class="card-count"><xsl:value-of select="count($main)"/></span>
</div>
<ul class="url-list">
<xsl:for-each select="$main">
<li class="url-item">
<a href="{sitemap:loc}"><xsl:value-of select="sitemap:loc"/></a>
<xsl:if test="sitemap:lastmod">
<div class="meta"><xsl:value-of select="sitemap:lastmod"/></div>
</xsl:if>
</li>
</xsl:for-each>
</ul>
</div>
</xsl:if>
<!-- Content pages -->
<xsl:variable name="content" select="sitemap:urlset/sitemap:url[
string-length(substring-after(substring-after(sitemap:loc, '://'), '/')) &gt;= 2
]"/>
<xsl:if test="count($content) &gt; 0">
<div class="card">
<div class="card-header">
<span class="card-title">Content</span>
<span class="card-count"><xsl:value-of select="count($content)"/></span>
</div>
<ul class="url-list">
<xsl:for-each select="$content">
<xsl:sort select="sitemap:loc"/>
<li class="url-item">
<a href="{sitemap:loc}"><xsl:value-of select="sitemap:loc"/></a>
<xsl:if test="sitemap:lastmod">
<div class="meta"><xsl:value-of select="sitemap:lastmod"/></div>
</xsl:if>
</li>
</xsl:for-each>
</ul>
</div>
</xsl:if>
</div>
<p style="margin-top: 2rem; text-align: center; color: #94a3b8; font-size: 12px;">
Generated by PhoenixKit
</p>
<script>
// Auto-reload on style change
(function() {
var currentStyle = 'cards';
var prefix = window.location.pathname.replace('/sitemap.xml', '');
var checkUrl = prefix + '/sitemap/version';
function checkVersion() {
fetch(checkUrl, { cache: 'no-store' })
.then(function(r) { return r.json(); })
.then(function(data) {
if (data.style &amp;&amp; data.style !== currentStyle) {
window.location.reload();
}
})
.catch(function() {});
}
setInterval(checkVersion, 3000);
})();
</script>
</body>
</html>
</xsl:template>
</xsl:stylesheet>