[Из песочницы] Красивый листинг файлов и директорий в nginx

Для web-сервера Apache существует множество инструкций, в том числе и на Хабре, как стилизовать стандартный листинг файлов и директорий. Однако, как сделать также для сервера nginx, в русскоязычном интернете не найти. Порывшись на просторах интернета я нашел один репозитарий, где как раз и решается этот вопрос. Но для кириллических наименований файлов и папок потребовалась небольшая работа «напильником».


ugj9askksvzkpvh6s200lwdefni.png


Итак имеется Ubuntu 16.04 и nginx 1.10.3. Настроим красивый листинг.


Скопируем директорию проекта BetterListing к себе на сайт. Чтобы она не отображались в листинге я переименовал /betterlisting на /.html сделав ее невидимой. При этом важно не забыть поменять соответствующие ссылки в файлах проекта. Также создадим директорию ./html/icons и поместим туда иконки для известных расширений в формате »расширение файла.png». Автор BetterListing предлагает использовать иконки Faenza Icons 96×96 пикс., но можно использовать и свои. По умолчанию в проекте известны расширения "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", но их легко изменить добавив или удалив нужные в код JS, который формирует вывод иконок.


Для тех, кому лень искать иконки

https://drive.google.com/drive/folders/1cpH8-utX-GpIsp6VIWHwjpcHSVU17DGS


За стандартный листинг в nginx отвечает модуль ngx_http_autoindex_module. Включим его для корневой директории.


location / {
               autoindex on;
               autoindex_localtime on;
               autoindex_exact_size off;
        }


Модуль ngx_http_addition_module — это фильтр, добавляющий текст до и после ответа сервера. То есть до и после тегов и  соответственно в странице сформированной модулем ngx_http_autoindex_module. Подключим файлы top.html и bot.html из проекта BetterListing.



               add_before_body /.html/top.html;
               add_after_body /.html/bot.html;


Поскольку в файлах top.html и bot.html уже присутствуют теги , , , , и , то нам необходимо отфильтровать повторяющиеся из стандартного вывода. За это отвечает модуль ngx_http_sub_module — это фильтр, изменяющий в ответе одну заданную строку на другую.



               sub_filter '' '';
               sub_filter 'Index of $uri' '';
               sub_filter '' '';
               sub_filter '' '';
               sub_filter '' '';
               sub_filter_once on;


Укажем кодировку UTF-8 иначе в кириллических именах nginx выставляет неправильное количество пробелов для выравнивания.


pp0uxewzcozfnq7h8shala2xs8k.png


 charset   utf-8;


В результате location / будет иметь вид:
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 '' '';
               sub_filter 'Index of $uri' '';
               sub_filter '' '';
               sub_filter '' '';
               sub_filter '' '';
               sub_filter_once on;
               #Кодировка страниц UTF8 для правильного выравнивания файлов и директорий с кириллическими символами
               charset   utf-8;
        }


Отредактируем ссылки в файле top.html. Также (необязательно) я вынес код JS в отдельный файл betterlisting.js и сделал загрузку bootstrap.min.css (Bootstrap v3.3.7) и jquery-3.3.1.min.js локально.


top.html







        
                
                Загрузки
                

                
                

                
                

                
                

                
                

                
                
                
                
                

        

        
                


В файле bot.html настроим свой футер, а для тегов и  добавим пробел, чтобы ngx_http_sub_module их не отфильтровал.


bot.html
        
                                


Теперь внесем изменения в код JS, который мы поместили в betterlisting.js. Этот скрипт отвечает за добавление иконок, фильтр файлов (поиск по странице) и переназначение вывода некоторых строк, поэтому каждый будет настраивать его под свои нужды. Стоит обратить внимание, что для корректной работы с кириллическими именами в функции filter (target) отвечающей за поиск по странице нужно изменить переменную arraySearch на decodeURIComponent (arraySearch). Для редактирования списка известных типов файлов внесите соответствующие изменения в переменную var formats.


betterlisting.js
            //
            // 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('

логотип

'); 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('

Загрузить: ' + dirTrun.slice(0) + '

'); // Add search box. $("h1").prepend('
'); // Add parent directory bit. $("a").eq(1).html('Parent Directory'); // Add titles. $("pre").prepend('
Name Time Size
'); // 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('


В файле style.css нужно подключить моноширинные шрифты с поддержкой кириллицы, которой нет в оригинальном проекте BetterListing и соответственно назначить их для класса .pre. Здесь же можно внести свои »украшалки» для листинга.


style.css
@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;
}


В результате листинг будет выглядеть, как-то так:


ifua-f1rxplz7fqb7lmsllm3elg.png


Ссылку на рабочий вариант могу указать по запросу в комментариях.

© Habrahabr.ru