WordPress è un fantastico CMS – Anzi, non ho più dubbi: è il miglior CMS! Ma – ahimé – nemmeno WordPress è perfetto e la sua imperfezione, a mio parere, deriva dal suo immenso database di plugin che spesso, purtroppo, sono obsoleti o scritti letteralmente coi piedi, o solo di facciata per spingerti a passare ad una versione a pagamento 😐
Questo, se da una parte porta ad una vastità smodata di possibilità, dall’altra porta anche ad avere a che fare con prodotti terribilmente vecchi, buggati, che piazzano il loro codice per l’intero blog anche se – esempio – dovrebbero lavorare solo nel backend, o solo su una specifica pagina, ecc ecc…
A causa di ciò, faccio quanto in mio potere per evitare plugin minori, con poche o scarse recensioni, dove l’autore non risponde mai (plugin abbandonati o quasi).
Per fare ciò, quando possibile, mi faccio dei plugin per conto mio e sfrutto delle funzioni di wordpress nel mio custom-function.php
Codice mio, testato e verificato, fa solo quello che dico io e come lo voglio io. No more, no less 😛
Dopo questa dovuta premessa, ecco che arrivo al punto: “L’Area Download”!
Ho provato tutti i plugin presenti sul database wordpress, ma ce ne fosse stato uno che mi sia piaciuto davvero 🙁
L’ultimo testato era: wp-downloadmanager
Old style, alcuni bug, ma – nonostante ciò – decisamente migliore di tanti altri.
In ogni caso, non pienamente soddisfatto, ho provato a fare da me.
In un primo momento pensavo di sfruttare un mio vecchio script:
SimpleFileList > Download + Demo
Ma avrei dovuto migliorarlo per renderlo ricorsivo, dargli un po’ di colore ecc… così ho preferito lavorare su una soluzione diversa che mi permettesse, tra l’altro, di scriverci su un articoletto interessante.
Ecco dunque che ho realizzato un’area download senza index, sfruttando mod_autoindex, insomma, e l’ho abbellita niente male con una serie di regole che adesso vi racconterò 🙂
La guida richiede una discreta conoscenza dell’.htaccess, che il sito sia ospitato su hosting con server apache, e che sia abilitato il modulo mod_autoindex (directory listing).
Possiamo iniziare verificando il tutto creando via ftp una directory di lavoro (eg: _download) e quindi creiamo un .htaccess dentro questa directory (e, magari, anche qualche directory o qualche file di esempio).
Apriamo il nuovo .htaccess appena creato, e aggiungiamo questa riga per verificare che tutto funzioni: Options +Indexes
Fatto ciò, andando su: http://nostrosito.**/_download, dovremmo ritrovarci una struttura simile (diversamente … o abbiam sbagliato qualcosa, o mod_autoindex è disabilitato dall’hosting e lì posso fare ben poco per aiutarvi: chiedete assistenza a loro e incrociate le dita):
Lo so, avete perfettamente ragione!
Graficamente è penosa come lista!
Ma vi garantisco che siamo solo all’inizio 😀
Proviamo a migliorare le cose aggiungendo IndexOptions FancyIndexing
al nostro htaccess.
Ricarichiamo la pagina, e adesso dovremmo ritrovarci qualcosa del genere (il che è già un po’ meglio):
E se volessimo aggiungere delle icone?
Una descrizione?
Cambiare l’ordine di default?
Inserire un css?
Magari aggiungere un po’ di javascript per fare alcuni fix al sorgente (eg: cambiare il titolo)?
Tutto possibilissimo, e anche relativamente semplice, grazie alla documentazione su apache.org:mod_autoindex
No, ok, spiegarvi ogni singola riga dell’htaccess potrebbe diventare noioso!
Io lo pubblico per intero, ed ha i suoi commenti.
Le singole funzioni – per i desiderosi di sapere – sono ben descritte nella pagina della documentazione apache precedentemente linkata 😉
Il mio attuale codice!
/_download/.htaccess
# No fileindex DirectoryIndex none.none ## Enable Indexing Options +Indexes ## deny hotlink by referer <IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{HTTP_REFERER} !^$ RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?miosito.xx [NC] RewriteCond %{REQUEST_URI} !^/_download/_struttura/ [NC] RewriteRule ^(.*)$ "https://www.miosito.xx/download/#(goto):$1" [L,R,NE] </IfModule> # Security and force download! <Files *.*> Options -ExecCGI Header set Content-Disposition attachment RemoveHandler .cgi .php .php3 .php4 .php5 .phtml .pl .py .pyc .pyo </Files> # fix issue with url files :P <Files *.url> ForceType application/octet-stream </Files> # Set options IndexOptions FancyIndexing HTMLTable FoldersFirst iconsAreLinks Charset=UTF-8 XHTML DescriptionWidth=50 NameWidth=50 IndexOrderDefault Descending Date # Css + Header + Footer IndexHeadInsert "<script type='text/javascript' src='/_download/_struttura/js/global.js'></script>" IndexStyleSheet /_download/_struttura/css/style.css HeaderName /_download/_struttura/html/header.html ReadmeName /_download/_struttura/html/footer.html # ExcludeList IndexIgnore _struttura # Set icon DefaultIcon /_download/_struttura/icons/help.png AddIcon (parent,/_download/_struttura/icons/house_go2.png) .. AddIcon (tick,/_download/_struttura/icons/tick.png) ^^BLANKICON^^ AddIcon (folder,/_download/_struttura/icons/folder.png) ^^DIRECTORY^^ AddIcon (url,/_download/_struttura/icons/world_link.png) .url AddIcon (music,/_download/_struttura/icons/music.png) .mp3 AddIcon (txt,/_download/_struttura/icons/text_signature.png) .txt AddIcon (pdf,/_download/_struttura/icons/page_white_word.png) .doc .docx AddIcon (pdf,/_download/_struttura/icons/page_white_acrobat.png) .pdf AddIcon (odt,/_download/_struttura/icons/text_signature.png) .odt AddIcon (css,/_download/_struttura/icons/css.png) .css AddIcon (php,/_download/_struttura/icons/page_white_php.png) .php .php3 .php4 .php5 AddIcon (html,/_download/_struttura/icons/html.png) .htm .html AddIcon (images,/_download/_struttura/icons/photos.png) .jpg .jpeg .png .gif .bmp AddIcon (archive,/_download/_struttura/icons/compress.png) .zip .rar .gzip .tar AddIcon (terminal,/_download/_struttura/icons/application_view_list.png) .exe .msi AddIcon (terminal,/_download/_struttura/icons/application_xp_terminal.png) .exe .bat .cmd ##### descr max 50 bytes!!! ##### AddDescription "[Top^]" .. # Folder descriptions (+quotes if has spaces)! AddDescription "doc, xls, pdf, txt, ecc" Documenti AddDescription "Php/Html Script" "Script & CMS" AddDescription "ecv template+istruzioni" "Europass CV - IT" AddDescription "Programmi e Utility" Software AddDescription "Router Firmware/Utility" "Firmware & Modding" # File descriptions AddDescription "File batch" .bat .cmd AddDescription "Mp3 File" .mp3 AddDescription "GZIP TAR archive" .tgz .tar.gz AddDescription "GZIP archive" .Z .z .gz .zip AddDescription "RAR archive" .rar AddDescription "TAR archive" .tar AddDescription "ZIP archive" .zip AddDescription "Executable Win. Files" .exe AddDescription "Windows Installer" .msi AddDescription "CGI Script" .cgi AddDescription "Jpeg Image" .jpg .jpeg .jpe AddDescription "Gif Image" .gif AddDescription "Png Image" .png AddDescription "Vector graphic" .ps .ai .eps AddDescription "Html file" .html .shtml .htm AddDescription "Css file" .css AddDescription "DocType Definition" .dtd AddDescription "Xml file" .xml AddDescription "Compressed HTML help" .chm AddDescription "Pdf File" .pdf AddDescription "Plain text file" .txt .nfo .faq .readme AddDescription "Unix man page" .man AddDescription "Email data" .eml .mbox AddDescription "MS Word document" .doc .docx AddDescription "OpenDocument" .odt AddDescription "PHP Script" .php .php3 .php4 AddDescription "PHP source code" .phps AddDescription "Javascript" .js AddDescription "Java code" .java AddDescription "Unix shell script" .sh .shar .csh .ksh .command AddDescription "Mac OS X shell script" .command AddDescription "Configuration file" .conf AddDescription "Mac OS X terminal" .term AddDescription "BitTorrent file" .torrent AddDescription "Windows link" .lnk .url # Default description AddDescription "[unknown item..]" *
/_download/_struttura/css/style.css
#h1indexlist { font: 2em Georgia, serif } #indexlist { font: .9em/1.3em "Courier New", Courier; border-spacing: 0; color: #777 } #indexlist img { margin: 3px 0 } #indexlist a:link, #indexlist a:visited { text-decoration: none } #indexlist a:link { color: #555 } #indexlist a:visited { color: #777 } #indexlist a:active, #indexlist a:hover { text-decoration: underline; color: #007acc } #indexlist tr { line-height: 35px } #indexlist td { padding: 5px; } #indexlist th { padding: 0 5px; } #indexlist tr.even { background-color: #F7F7F7 } #indexlist tr.odd { background-color: #DAE6F5 } #indexlist .indexcolicon { text-align: left } #indexlist .indexcolname { width: 35%; text-align: left } #indexlist .indexcollastmod, #indexlist .indexcolsize { text-align: center } #indexlist .indexcoldesc { width: 25%; text-align: right } #indexlist .indexcollastmod { width: 25% } #indexlist .indexcolsize { width: 15% } #indexfooterurl { line-height: 30px; } #indexfooterurl a { color: #007acc }
/_download/_struttura/html/header.html
<h1 id="h1indexlist"></h1><!-- used via innerHTML -->
/_download/_struttura/html/footer.html
<div id="indexfooterurl"></div><!-- used via innerHTML --> <script type='text/javascript' src='/_download/_struttura/js/iframeResizer.contentWindow.min.js'></script> <!-- source: https://raw.githubusercontent.com/davidjbradshaw/iframe-resizer/master/js/iframeResizer.contentWindow.min.js -->
/_download/_struttura/js/global.js
////////// // Config: var _new_title = 'Root'; var _dir_path = '_download'; var _iframe_uri = 'download'; var _root_title = 'Index of /' + _dir_path + ''; var _iframe_page_title = 'Download - L’AltroWeb'; // iframe title page // set fixedtitle var var _fixedtitle = document.title // set wlh var var _wlh = window.location.href; _wlh = _wlh.replace(_dir_path + '/', _iframe_uri + '/'); // set hash: var _hash = _wlh.replace(_iframe_uri + '/', _iframe_uri + '/#(goto):'); ////////// // allow only inside iframe! if (self == top) { if (document.title == _root_title) { window.location.href = _wlh; //redirect } else { _wlh = _hash; window.location.href = _wlh; //redirect } } else { if (document.title == _root_title) { // add css if is root directory: document.write('<style type="text/css">tbody tr.even:nth-child(3){display:none}</style>'); } else { // else add hash: _wlh = _hash; } // then > update url: if (top.document.title == _iframe_page_title) { top.history.pushState(null, null, _wlh); } } // innerHTML: window.onload = function() { _fixedtitle = _fixedtitle.replace(_root_title, _new_title); _fixedtitle = _fixedtitle.replace(/\//g, ' > '); document.getElementById("h1indexlist").innerHTML = _fixedtitle; document.getElementById("indexfooterurl").innerHTML = 'url: <a href="' + _wlh +'" title="Link diretto" target="_top">' + decodeURIComponent(_wlh) +'</a>'; }
Pagina Download
<script type="text/javascript"> // accept anchor as link var _wlh = window.location.hash; if (_wlh.match(/\#\(goto\)\:/g)) // > eg: fix tag tag-more! { _wlh = _wlh.replace('#(goto):', ''); } else { _wlh = ''; } document.write('<iframe src="/_download/' + _wlh + '" frameborder="0" scrolling="no" style="width:100%;border:0"></iframe>'); </script> <!-- source: //raw.githubusercontent.com/davidjbradshaw/iframe-resizer/master/js/iframeResizer.min.js --> <script type="text/javascript" src="/_download/_struttura/js/iframeResizer.min.js"></script> <script type="text/javascript">iFrameResize()</script> <noscript> <p>download area: <a href="/_download/" title="noscript release">https://www.miosito.xx/_download/</a></p> </noscript>
Icone:
Come si può notare è dunque un iframe corretto via javascript (ci ho dovuto lavorare un po’, ma adesso – a mio parere – funiona benissimo e mi piace davvero molto così)!
Risultato ftp:
Come possiamo notare abbiamo l’htaccess nella root;
le varie directory che formeranno le categorie della nostra area download;
la directory “_struttura” (nascosta dall’area download grazie a IndexIgnore _struttura
)
nessun file index.php o html (se li mettessimo sarebbero semplicemente presenti in lista e disponibili al download grazie a DirectoryIndex none.none
) 😉
Risultato browser:
Beh, direi che il miglioramento è davvero niente male, non trovate? 🙂
Questi i miei colori e il mio personale gusto. A voi basterà modificare il file .css per meglio adattarlo alle vostre esigenze.
Bene, spero sia tutto abbastanza chiaro e il codice sufficiente per permettere anche a voi, voi che usate wordpress, drupal, joomla, o un semplice sito in html (ma sempre su server apache), di creare – a vostro piacimento – la vostra area download.
Volete migliorarvi con WordPress? Qui alcuni titoli interessanti:
[amazon_link asins=’8850333234,8820363585,8820372916,8820374773,8820378205,8850332033,B00Y06B37E,B01MZ63P01,8848129668′ template=’ProductCarousel’ store=’lal0a-21′ marketplace=’IT’ link_id=’a45b2d00-d466-11e6-a175-e37475b2e297′]
Per ogni domanda o dubbio, ovviamente, non esitate a chiedere 😉
—
PS: trovate l’intera struttura direttamente in un archivio zip, nella stessa area download: ./Script & CMS/_download_htaccess-script.zip
Thank you Salvadore. I copied all files and insert the last part “Download page” in a WordPress post. but it didn’t work.
Thanks for comment!
Please, check archive inside download > Script & CMS.
–
Just upload in root directory, fix htaccess and js with your domain.
If your server is ok, i think can work 🙂
Did it! I download “iframeResizer.contentWindow.min.js” and “iframeResizer.min.js” too. Now I’m working on modifying titles, paths, CSS. How can I change the files paths to another location?
Another question is about the security aspects. is this script safe enough to use it in a production server?
iframeResizer.min.js is and iframeResizer.contentWindow.min.js are already in archive 😉
–
u can rename directory and modify htaccess with a good editor
search: “_download”
replace “new_name”
–
same in javascript and in html files (with notepad++ u can search and replace in *files with one click).
–
please, stay attention to not generate conflict with others url (eg: wp-slug)
for this i’ve used an underscore with a very simple/little name.
–
security: upload is from ftp (by admin).
not upload private data and no security issue can exist.
php, cgi etc are disabled by htaccess! then, no problem with this.
# Security and force download!
Options -ExecCGI
Header set Content-Disposition attachment
RemoveHandler .cgi .php .php3 .php4 .php5 .phtml .pl .py .pyc .pyo
Now it is working. I really thank you for your help 🙂 . There are some few questions. when I am in root folder I still have “.. parent folder”. It should detect that there is no parent folder an I think you have done it by defining “var _iframe_page_title =” with “title of page” + ” – ” + title of your blog in global.js and activate “display=none” in a condition. But mine doesn’t work.
next, where should I add “direction:rtl;” to change the files table direction?
no, i fixed this with:
if (document.title == _root_title)
{
// add css if is root directory:
document.write('<style type="text/css">tbody tr.even:nth-child(3){display:none}</style>');
}
rtl: i think u can define via css > http://www.w3schools.com/cssref/tryit.asp?filename=trycss_text_direction
eg, if u want only for colon name (filename):
#indexlist .indexcolname {
width: 35%;
text-align: left;
direction: rtl; /* add this in css block for rtl */
}
I think the problem is using the script on localhost (xampp) in detecting correct iframe and document URI. It doesn’t add “localhost” in URI. I am looking for the place that I have to add “‘localhost/’+” or something like that. I’m sure that it will work on an online server.
Thanks Salvatore for your useful script.
i never test in localserver, sorry.
i hope can be ok when u publish in live server.
kind regards,
S.N. 🙂