Jeśli dobrze cię rozumiem, chcesz mieć adres URL podobny do następującego, którego odpowiedzią dla przeglądarki będzie treść, którą generujesz, tj. .CSV
Plik i żadna treść generowana z WordPress?
http://example.com/download/data.csv
Myślę, że szukasz 'template_redirect'
haka. Można znaleźć 'template_redirect'
w /wp-includes/template-loader.php
którym jest plik wszyscy deweloperzy WordPress powinien zapoznać się z; jest krótki i słodki i kieruje każdą ładowaniem stron innych niż administrator, więc koniecznie spójrz na to.
Po prostu dodaj następujące elementy do functions.php
pliku motywu lub w innym pliku, include
w którym się znajdujesz functions.php
:
add_action('template_redirect','yoursite_template_redirect');
function yoursite_template_redirect() {
if ($_SERVER['REQUEST_URI']=='/downloads/data.csv') {
header("Content-type: application/x-msdownload",true,200);
header("Content-Disposition: attachment; filename=data.csv");
header("Pragma: no-cache");
header("Expires: 0");
echo 'data';
exit();
}
}
Zanotuj test '/downloads/data.csv'
adresu URL, sprawdzając $_SERVER['REQUEST_URI']
. Zwróć także uwagę na dodane ,true,200
do header()
połączenia, gdzie ustawiłeś Content-type
; dzieje się tak, ponieważ WordPress ustawi kod statusu 404
„Nie znaleziono”, ponieważ nie rozpoznaje adresu URL. Nie stanowi to jednak problemu, ponieważ true
nakazuje header()
zastąpienie 404
WordPressa ustawieniem i użycie zamiast tego kodu stanu HTTP 200
„OK” .
A oto, jak to wygląda w FireFox ( zwróć uwagę, że zrzut ekranu nie ma /downloads/
katalogu wirtualnego, ponieważ po zrobieniu zrzutu ekranu i opatrzeniu go adnotacją po prostu wydawało się dobrym pomysłem dodanie '/downloads/'
katalogu wirtualnego):
(źródło: mikeschinkel.com )
AKTUALIZACJA
Jeśli chcesz, aby pobieranie odbywało się na podstawie adresu URL z prefiksem, /wp-admin/
aby dać użytkownikowi wizualne wskazanie, że jest chroniony przez login, możesz to również zrobić; opis jednego ze sposobów jest następujący.
I obudowane w klasie, tym razem o nazwie DownloadCSV
, a także tworzone przez użytkownika „zdolności” o nazwie 'download_csv'
dla 'administrator'
roli (czytaj o roli i kompetencji tutaj ) Możesz po prostu na barana off predefiniowanej 'export'
roli, jeśli lubisz, a jeśli tak, wystarczy wyszukać i zamienić 'download_csv'
z 'export'
i usuń register_activation_hook()
połączenie oraz activate()
funkcję. Nawiasem mówiąc, potrzeba haka aktywacyjnego jest jednym z powodów, dla których przeniosłem go do wtyczki zamiast przechowywać w functions.php
pliku motywu . *
Dodałem także opcję menu „Pobierz CSV” z menu „Narzędzia”, używając add_submenu_page()
i powiązałem ją z 'download_csv'
funkcją.
Wreszcie wybrałem 'plugins_loaded'
hak, ponieważ był to najwcześniejszy odpowiedni hak, którego mogłem użyć. Możesz użyć, 'admin_init'
ale ten hak jest uruchamiany znacznie później (1130. połączenie hakowe vs. 3. połączenie hakowe), więc po co pozwolić WordPressowi wykonywać więcej zadań wyrzucania, niż to konieczne? (Użyłem wtyczki Instrument Hooks, aby dowiedzieć się, którego haka użyć).
W haka I sprawdzić, moje starty URL z /wp-admin/tools.php
sprawdzając $pagenow
zmiennej I zweryfikować, current_user_can('download_csv')
a jeśli to przechodzi następnie przetestować $_GET['download']
, aby sprawdzić, czy zawiera on data.csv
; jeśli tak, uruchamiamy praktycznie ten sam kod jak poprzednio. Usuwam również ,true,200
wezwanie do header()
w poprzednim przykładzie, ponieważ tutaj WordPress wie, że to dobry adres URL, więc nie ustawiłem jeszcze statusu 404. Oto twój kod:
<?php
/*
Plugin Name: Download CSV
Author: Mike Schinkel
Author URI: http://mikeschinkel.com
*/
if (!class_exists('DownloadCSV')) {
class DownloadCSV {
static function on_load() {
add_action('plugins_loaded',array(__CLASS__,'plugins_loaded'));
add_action('admin_menu',array(__CLASS__,'admin_menu'));
register_activation_hook(__FILE__,array(__CLASS__,'activate'));
}
static function activate() {
$role = get_role('administrator');
$role->add_cap('download_csv');
}
static function admin_menu() {
add_submenu_page('tools.php', // Parent Menu
'Download CSV', // Page Title
'Download CSV', // Menu Option Label
'download_csv', // Capability
'tools.php?download=data.csv');// Option URL relative to /wp-admin/
}
static function plugins_loaded() {
global $pagenow;
if ($pagenow=='tools.php' &&
current_user_can('download_csv') &&
isset($_GET['download']) &&
$_GET['download']=='data.csv') {
header("Content-type: application/x-msdownload");
header("Content-Disposition: attachment; filename=data.csv");
header("Pragma: no-cache");
header("Expires: 0");
echo 'data';
exit();
}
}
}
DownloadCSV::on_load();
}
A oto zrzut ekranu aktywowanej wtyczki:
(źródło: mikeschinkel.com )
I wreszcie zrzut ekranu z pobieraniem:
(źródło: mikeschinkel.com )
'template_redirect'
to zdecydowanie działa na serwerze. Jeśli nie, byłbym całkowicie zdezorientowany; czy możesz wyjaśnić problem? Z góry dziękuję./downloads/data.csv
, który nie istnieje, więc „interfejs użytkownika” WordPressa obsłuży to żądanie i ostatecznie osiągnietemplate-redirect
. Wystarczy utworzyć link w obszarze administracyjnym, który wskazuje ten frontowy adres URL. (Trzeba powiedzieć, że w ten sposób nie otrzymujesz ochrony logowania administratora za darmo - każdy, kto zna adres URL, może pobrać plik, ale może istnieje łatwy sposób, aby to naprawić?)current_user_can()
z powyższym kodem lub zastosować inne podejście. Po tym komentarzu dodam aktualizację do mojej odpowiedzi.jeszcze jedna przydatna wtyczka do eksportu do CSV. może być przydatny dla kogoś
źródło
admin_init Zaczep lub ładowanie (strona) Zaczep wydaje się działać, WordPress nie ma ustawionego nagłówka w tym stanie. Używam haka load- (page), ponieważ działa, gdy załadowana jest strona menu administracyjnego. Możesz załadować skrypt dla określonej strony.
Możesz sprawdzić load- (page) Hook na WordPress Codex
Jeśli używasz admin_init Hook, upewnij się, że zweryfikowałeś nonce za pomocą check_admin_referer lub innego skryptu, może się zda, że warunek uzyska wynik pobierania pliku.
źródło