nginx的autoindex,目录浏览,配置和美化,美观的xslt_stylesheet
Nginx custom autoindex with XSLT
转载注明来源: 本文链接 来自osnosn的博客,写于 2019-04-11.
- 另有个项目,用php写的单文件,显示文件目录。https://github.com/osnosn/autoindex
需要在浏览器页面中浏览服务器的目录。Apache2很容易配置,还能通过配置让目录浏览显示比较美观。
Nginx也很容易配置,Nginx提供了相应的ngx_http_autoindex_module 模块,该模块提供了我们想要的功能。
例如,要让/bt/
目录能显示,nginx的配置这样写:
location ^~ /bt/ {
autoindex on;
autoindex_format html;
#autoindex_localtime off;
charset utf-8;
include /etc/nginx/default.d/php71w-fpm.conf;
}
文件修改时间,可用参数autoindex_localtime
设置为utc或当地时间。
效果如下图,可惜不太美观:
那再用上 ngx_http_xslt_module 模块。
长文件名溢出自动显示省略号。效果如下:
nginx配置如下:
location ^~ /bt/ {
autoindex on;
autoindex_format xml;
xslt_stylesheet /data/www/html/autoindex.xslt cpath="$uri";
include /etc/nginx/default.d/php71w-fpm.conf;
}
autoindex.xslt 这个文件有点大。
似乎ngx_http_xslt_module只支持stylesheet-1.0,不支持2.0。但支持libexslt,可以使用EXSLT函数。
xml中只提供UTC时间。不能通过nginx的配置修改。
时区修改在xslt文件中,TIMEDIFF
变量。
改为PT0H
时间不变,PT8H
加8小时,-PT6H
减6小时。
autoindex.xslt文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:date="http://exslt.org/dates-and-times"
extension-element-prefixes="date" >
<xsl:output method="html" encoding="UTF-8"/>
<xsl:param name="cpath"/>
<xsl:variable name="TIMEDIFF" select="'PT8H'"/><!-- 'PT0H' '-PT6H' -->
<xsl:template match="/">
<xsl:text disable-output-escaping="yes"><!DOCTYPE html></xsl:text>
<html>
<head>
<title>IndexOf <xsl:value-of select="$cpath"/></title>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<xsl:text disable-output-escaping="yes">
<!--
========= config in nginx: ===============
autoindex on;
autoindex_format xml;
xslt_stylesheet /..path_to.../html/autoindex.xslt cpath="$uri";
========= config in nginx: ===============
modify variable "TIMEDIFF".
-->
</xsl:text>
<style type="text/css">
body {
margin: 5px;
background-color: #ddd;
}
table {
font-size: 15px;
width: 96%;
min-width:650px;
table-layout:fixed;
margin-top: 15px;
margin-left: 5px;
margin-right: 5px;
box-shadow: 0 0 0.5em #999;
border: none !important;
margin-bottom: 1em;
border-collapse: collapse;
border-spacing: 0;
}
th {
background: #000;
background: -webkit-linear-gradient(top, #444, #000);
background: -moz-linear-gradient(top, #444, #000);
background: -ms-linear-gradient(top, #444, #000);
background: -o-linear-gradient(top, #444, #000);
background: linear-gradient(top, #444, #000);
font-size: 14px;
line-height: 24px;
border: none;
text-align: left;
color: #fff;
}
tr {
background: rgba(255, 255, 255, 0.8);
}
tr:hover {
background: rgba(255, 255, 255, 0.5);
}
.f9 {
font-size: 9px;
}
tr th td {
overflow:hidden;
text-overflow:ellipsis;
white-space:nowrap;
word-break:keep-all;
}
th, td {
height: 20px;
vertical-align: middle;
white-space: nowrap;
padding: 0.1em 0.5em;
border: 1px solid #ccc;
}
a{text-decoration:none;}
a:hover{text-decoration:underline;}
.name{min-width:400px;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;font-size:15px;}
.size{min-width:65px;white-space:nowrap;font-size:13px;text-align:right;}
.mtime{width:115px;white-space:nowrap;font-size:11px;text-align:center;}
</style>
</head>
<body>
<div style="margin-left:15px;margin-top:10px;font-size:15pt">
<b>
Index of <xsl:value-of select="$cpath"/>
</b>
</div>
<center>
<xsl:apply-templates/>
</center>
<div style="margin-left:10px;font-size:9pt">:.end</div>
<br/>
</body>
</html>
</xsl:template>
<xsl:template match="list">
<table style="width:100%;min-width:670px;margin:0;box-shadow:none" cellpadding="0"><tr style="background:none"><td style="padding:0;border:0"><center>
<table>
<tr>
<th>Name</th>
<th width="80px">Size</th>
<th width="115px">Modified</th>
</tr>
<tr>
<td><a href="../">../</a></td>
<td></td>
<td></td>
</tr>
<xsl:for-each select="directory">
<xsl:sort select="name"/>
</xsl:for-each>
<xsl:apply-templates/>
</table>
</center></td></tr></table>
</xsl:template>
<xsl:template match="file">
<xsl:variable name="name">
<xsl:value-of select="."/>
</xsl:variable>
<xsl:variable name="size">
<xsl:if test="string-length(@size) > 0">
<xsl:if test="number(@size) = 0">
<xsl:value-of select="@size" /> B
</xsl:if>
<xsl:if test="number(@size) > 0">
<xsl:choose>
<xsl:when test="round(@size div 1024) < 2"><xsl:value-of select="@size" /> B</xsl:when>
<xsl:when test="round(@size div 1048576) < 2"><xsl:value-of select="format-number((@size div 1024), '0.0')" /> KB</xsl:when>
<xsl:when test="round(@size div 1073741824) < 2"><xsl:value-of select="format-number((@size div 1048576), '0.00')" /> MB</xsl:when>
<xsl:otherwise><xsl:value-of select="format-number((@size div 1073741824), '0.00')" /> GB</xsl:otherwise>
</xsl:choose>
</xsl:if>
</xsl:if>
</xsl:variable>
<tr>
<td class="f11"><div class="name"><a href="{$name}" title="{$name}"><xsl:value-of select="."/></a></div></td>
<td><div class="size" title="{@size} bytes"><xsl:value-of select="$size"/></div></td>
<td><div class="mtime">
<xsl:value-of select="translate(date:add(@mtime,$TIMEDIFF),'TZ',' ')" />
</div></td>
</tr>
</xsl:template>
<xsl:template match="directory" name="directory">
<xsl:variable name="name">
<xsl:value-of select="."/>
</xsl:variable>
<tr>
<td class="f11"><div class="name"><a href="{$name}" title="{$name}/"><xsl:value-of select="."/>/</a></div></td>
<td><div class="size"> -- </div></td>
<td><div class="mtime">
<xsl:value-of select="translate(date:add(@mtime,$TIMEDIFF),'TZ',' ')" />
</div></td>
</tr>
</xsl:template>
</xsl:stylesheet>