For the Apache web server, there are many instructions, including on Habré , how to style the standard listing of files and directories. However, how to make also for the nginx server, in the Russian-speaking Internet not to find. Having rummaged on the Internet, I found one repository , where this issue is being solved. But for the Cyrillic names of files and folders it took a little work "file".
So there is Ubuntu 16.04 and nginx 1.10.3. Set up a beautiful listing.
Copy the directory of the BetterListing project to your website. So that it does not appear in the listing, I renamed / betterlisting to /.html making it invisible. It is important not to forget to change the corresponding links in the project files. We will also create a directory ./html/icons and place icons for known extensions in the format "file extension.png " there. The author of BetterListing suggests using Faenza Icons 96x96 pixels, but you can use your own. By default, the project knows the extensions "bin", "jpg", "gif", "png", "html", "css", "zip", "iso", "tiff", "ico", "psd", "pdf", "exe", "rar", "deb", "swf", "7z", "doc", "docx", "xls", "xlsx", "pptx", "ppt", "txt", "php", "js", "c", "c++", "torrent", "sql", "wmv", "avi", "mp4", "mp3", "wma", "ogg", "msg", "wav", "py", "java", "gzip", "jpeg", "raw"
, but they can be easily changed by adding or removing the necessary ones in the JS code, which forms the output of icons.
The module ngx_http_autoindex_module is responsible for the standard listing in nginx. Enable it for the root directory.
location / { autoindex on; autoindex_localtime on; autoindex_exact_size off; }
The ngx_http_addition_module module is a filter that adds text before and after the server’s response. That is, before and after the <html>
and </html>
tags, respectively, in the page formed by the ngx_http_autoindex_module module. Let's connect the top.html and bot.html files from the BetterListing project.
add_before_body /.html/top.html; add_after_body /.html/bot.html;
Since the top.html and bot.html files already contain the <html>
, <head>
, </head>
, <body>
, </body>
and </html>
tags, we need to filter the duplicate from the standard output. The ngx_http_sub_module module is responsible for this — it is a filter that changes one specified string to another in the response.
sub_filter '<html>' ''; sub_filter '<head><title>Index of $uri</title></head>' ''; sub_filter '<body bgcolor="white">' ''; sub_filter '</body>' ''; sub_filter '</html>' ''; sub_filter_once on;
We specify the UTF-8 encoding, otherwise in Cyrillic names, nginx sets the wrong number of spaces to align.
charset utf-8;
location / { try_files $uri $uri/ =404; # top.html bot.html add_before_body /.html/top.html; add_after_body /.html/bot.html; autoindex on; autoindex_localtime on; autoindex_exact_size off; # sub_filter '<html>' ''; sub_filter '<head><title>Index of $uri</title></head>' ''; sub_filter '<body bgcolor="white">' ''; sub_filter '</body>' ''; sub_filter '</html>' ''; sub_filter_once on; # UTF8 charset utf-8; }
Edit the links in the top.html file. Also ( optional ) I rendered the JS code into a separate file betterlisting.js and did the bootstrap.min.css ( Bootstrap v3.3.7 ) and jquery-3.3.1.min.js locally.
<!DOCTYPE html> <!-- BetterListing - devCoster.com --> <!-- Coster coster@devcoster.com --> <!-- Version 1.0a --> <html lang="ru-RU" prefix="og: http://ogp.me/ns#"> <head> <!-- Adjust title in settings below --> <title></title> <meta charset="utf-8" /> <!-- Bootstrap Core CSS--> <link rel="stylesheet" href="/.html/bootstrap/css/bootstrap.min.css"> <!-- Styles --> <link rel="stylesheet" href="/.html/style.css"> <!-- jQuery --> <script src="/.html/jquery-3.3.1.min.js"></script> <!-- BetterListing --> <script src="/.html/betterlisting.js"></script> <!-- Favicon --> <link rel="icon" href="/.html/logo.png" sizes="32x32" /> <link rel="icon" href="/.html/logo.png" sizes="192x192" /> <link rel="apple-touch-icon-precomposed" href="/.html/logo.png" /> <meta name="msapplication-TileImage" content="/.html/logo.png" /> </head> <body> <div class="wasContainer"> <div class="row"> <div class="col-xs-11 col-centered" id="mainBox"> <!-- Start of nginx output -->
In the bot.html file , configure your footer, and for the </body >
and </html >
tags, add a space so that ngx_http_sub_module does not filter them.
<!-- End of nginx output --> </div> </div> <div id="footer" class="row"> <!-- This footer will change depending on your settings in top.html --> <p class="text-center"><a href="*URL *"></a></p> </div> </div> <center> <!--LiveInternet counter--> <script type="text/javascript"><!-- document.write("<a href='https://www.liveinternet.ru/click' "+ "target=_blank><img src='//counter.yadro.ru/hit?t14.11;r"+ escape(document.referrer)+((typeof(screen)=="undefined")?"": ";s"+screen.width+"*"+screen.height+"*"+(screen.colorDepth? screen.colorDepth:screen.pixelDepth))+";u"+escape(document.URL)+ ";"+Math.random()+ "' alt='' title='LiveInternet: 24"+ " , 24 ' "+ "border='0' width='88' height='31'><\/a>") //--> </script> <!--/LiveInternet--> </center> </body > </html >
Now we will make changes to the JS code that we put in betterlisting.js . This script is responsible for adding icons, filtering files ( searching the page ) and reassigning the output of some lines, so everyone will customize it to fit their needs. It should be noted that to work correctly with Cyrillic names in the filter (target) function responsible for searching the page, you need to change the variable arraySearch to decodeURIComponent (arraySearch) . To edit the list of known file types, make the appropriate changes to the var formats variable.
// // Configure BetterListing here: var websiteName = ''; var websiteURL = '*URL *'; // End of normal settings. // $(document).ready(function(){ // Working on nginx HTML and applying settings. var text = $("h1").text(); var array = text.split('/'); var last = array[array.length-2]; var dirStructure = $("a").text(); var dirStructure = document.getElementsByTagName('a')[0].href; var dir = text.substring(10); var currentDir = last.charAt(0).toUpperCase() + last.slice(1); var dirTrun; // Truncate long folder names. if (currentDir.length > 19){ var currentDir = currentDir.substring(0, 18) + '...'; } // Updating page title. document.title = websiteName; // Add back button. $("h1").html('<p><img alt="" style="margin-top: 7px; margin-left: 0px; padding: -1px; border-radius: 5px; border: 1px solid #aaa;" src="/.html/logo2.png"></p>'); if (dir.length > 90) { dirTrun = dir.replace(/(.{90})/g, "$1\n") } else { dirTrun = dir.substring(0, dir.length - 1); } // Add subtitle and back arrow. $("h1").append('<h4><a href="' + dirStructure + '"></a><b>: </b>' + dirTrun.slice(0) + '</h4>'); // Add search box. $("h1").prepend('<form id="custom-search-form" class="form-inline pull-right"><div class="btn-group"><input id="searchBox" placeholder=" " type="search" class="form-control"> <span id="searchclear" class="glyphicon glyphicon-remove-circle"></span></div></form>'); // Add parent directory bit. $("a").eq(1).html('Parent Directory'); // Add titles. $("pre").prepend('<div class="header">Name Time Size</div>'); // Establish supported formats. var list = new Array(); var formats = ["bin", "jpg", "gif", "png", "html", "css", "zip", "iso", "tiff", "ico", "psd", "pdf", "exe", "rar", "deb", "swf", "7z", "doc", "docx", "xls", "xlsx", "pptx", "ppt", "txt", "php", "js", "c", "c++", "torrent", "sql", "wmv", "avi", "mp4", "mp3", "wma", "ogg", "msg", "wav", "py", "java", "gzip", "jpeg", "raw"]; // Run when text is entered in the search box. $('#custom-search-form').on('input',function(e){ e.preventDefault(); var target = $('#searchBox').val(); filter(target); }); // Instant search. function filter(target){ var parent_directory = 'parent directory'; $('pre a').each(function(){ var arraySearch = $(this).attr('href'); var arraySearch = decodeURIComponent( arraySearch ) // Check the href data for searched term. Using href because the link label truncates if the file or folder name is too long. // Special handling for 'Parent Directory' as the href data doesn't contain that word. if (arraySearch.toLowerCase().indexOf(target.toLowerCase()) > -1 || (($(this).text() == 'Parent Directory') && (parent_directory.indexOf(target.toLowerCase()) > -1))){ $(this).show(); $($(this)[0].nextSibling).css('display', 'inline'); } else { $(this).hide(); if($($(this)[0].nextSibling).hasClass('hideMe')) { $($(this)[0].nextSibling).css('display', 'none'); } else { $($(this)[0].nextSibling).wrap('<span class="hideMe" style="display:none"></style>'); } } }); } // Runs when clear button is hit. $("#searchclear").click(function(){ $("#searchBox").val(''); filter(''); }); // Scan all files in the directory, check the extensions and show the right MIME-type image. $('pre a').each(function(){ var found = 0; var arraySplit = $(this).attr('href').split("."); var fileExt = arraySplit[arraySplit.length - 1]; for (var i = 0; i < formats.length; i++) { if (fileExt.toLowerCase() == formats[i].toLowerCase()) { var found = 1; var oldText = $(this).text(); $(this).html('<img class="icons" src="/.html/icons/' + formats[i] + '.png"></img></a>' + oldText); return; } } // Add an icon for the go-back link. if ($(this).text().indexOf("Parent Directory") >= 0) { var found = 1; var oldText = $(this).text(); $(this).html('<img class="icons" src="/.html/icons/home.png">' + oldText); return; } // Check for folders as they don't have extensions. if ($(this).attr('href').substr($(this).attr('href').length - 1) == '/') { var found = 1; var oldText = $(this).text(); $(this).html('<img class="icons" src="/.html/icons/folder.png">' + oldText.substring(0, oldText.length - 1)); // Fix for annoying jQuery behaviour where inserted spaces are treated as new elements -- which breaks my search. var string = ' ' + $($(this)[0].nextSibling).text(); // Copy the original meta-data string, append a space char and save it over the old string. $($(this)[0].nextSibling).remove(); $(this).after(string); return; } // File format not supported by Better Listings, so let's load a generic icon. if (found == 0){ var oldText = $(this).text(); $(this).html('<img class="icons" src="/.html/icons/error.png">' + oldText); return; } }); });
In the style.css file, you need to connect monospaced fonts with Cyrillic support, which is not in the original BetterListing project and, accordingly, assign them to the .pre class. Here you can make your " decorators " for listing.
@import url('https://fonts.googleapis.com/css?family=Cousine&subset=cyrillic'); a { color: #4C4C4C; } body{ color: #4C4C4C; font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif; background: #F9F9F9 url(index.png) repeat; } pre{ font-family: 'Cousine', monospace; background-color: #FFFFFF; border: 1px solid #ccc; width: 750px; padding: 9.5px 0px 9.5px 0px; margin-top: 20px; text-align: left; } #footer{ margin-top: 20px; } #footer a{ color: #686868; } hr{ margin-bottom: 0px; } h4 { color: #aaa; margin-top: 10px; font-size: 40%; } .header { color: #686868; margin:3px 5px 6px 5px; } .icons { margin: 2px 5px 3px 5px; height: 4%; width: 4%; } .col-centered{ float: none; margin: 0 auto; } #mainBox{ width:766px; } .text-center{ margin-bottom: 20px; } #custom-search-form{ font-size: 15px; margin-top: 7px; } #searchIcon{ padding: 0px 0px 0px 5px; color: #686868; } .form-group-sm .form-control + .form-control-feedback, .input-group-sm + .form-control-feedback, .input-sm + .form-control-feedback { width: 30px; height: 30px; line-height: 30px; } .form-group-sm .form-control { height: 30px; padding: 5px 10px; font-size: 12px; line-height: 1.5; border-radius: 4px; } input.form-control,input.form-control:focus { border-color: #AAA; box-shadow: none; -webkit-box-shadow: none; -moz-box-shadow: none; -moz-transition: none; -webkit-transition: none; } #searchclear { position: absolute; right: 10px; top: 11px; height: 14px; margin: auto; font-size: 14px; cursor: pointer; color: #AAA; }
As a result, the listing will look something like this:
I can indicate the link to the working version upon request in the comments.
Source: https://habr.com/ru/post/353478/
All Articles