German (Deutsch) translation by Tatsiana Bochkareva (you can also view the original English article)
Im ersten Artikel haben wir uns angesehen, wie Sie eine Datei - insbesondere eine PDF-Datei - an WordPress-Beiträge und -Seiten anhängen können, ohne ein Plugin oder eine Lösung eines Drittanbieters verwenden zu müssen. Zu diesem Zeitpunkt können Sie nur Dateien hochladen. Es gibt keine Möglichkeit, den Link nach dem Hochladen tatsächlich zu deaktivieren oder den Link zu der Datei zu löschen. In diesem Beitrag sehen wir uns an, wie Sie den Download-Link etwas besser gestalten und die benutzerdefinierte Meta-Box-Funktionalität erweitern können, indem Benutzer Dateien löschen können, nachdem sie sie heruntergeladen haben.
Ziehen Sie es an
Wenn Sie dem Code im ersten Beitrag gefolgt sind, sollten Sie eine funktionale Demo haben, wie das Anhängen einer PDF-Datei an einen WordPress-Beitrag (oder eine WordPress-Seite) funktioniert. Die Gesamtdarstellung sieht jedoch nicht sehr gut aus:



Bevor wir fortfahren, lassen Sie uns dies ein wenig bereinigen, damit es ein bisschen besser in das Standardthema integriert aussieht. Denken Sie daran, dass wir Twentyeleven als Standardthema verwenden, damit wir alle auf derselben Seite sind, während wir das Tutorial durcharbeiten.
Verschieben wir zunächst den Download-Link an einen logischeren Ort. Wenn Sie seit dem ersten Beitrag mitverfolgt haben, werden Sie sich daran erinnern, dass wir den Download-Link in single.php platziert haben, das sich im Stammverzeichnis des Themenverzeichnisses befindet. Öffnen Sie die Datei und suchen Sie den Codeblock, der folgendermaßen aussieht:
1 |
get_template_part( 'content', 'single' ); |
2 |
$doc = get_post_meta(get_the_ID(), 'wp_custom_attachment', true); |
1 |
<a href=" <?php echo $doc['url']; ?>"> |
2 |
Download PDF Here |
3 |
</a>
|
Kopieren Sie alle bis auf die erste Codezeile und entfernen Sie sie aus der Datei. Dies sollte nur einen Aufruf von get_template_part hinterlassen.
Suchen Sie als Nächstes custom-single.php. Dies ist eine Vorlagendatei im Stammverzeichnis des Themenverzeichnisses. Suchen Sie den Aufruf von the_content() und fügen Sie den gerade kopierten Code direkt darunter ein. Dies sollte zu folgendem Codeblock führen:
1 |
the_content(); |
2 |
$doc = get_post_meta(get_the_ID(), 'wp_custom_attachment', true); |
3 |
<a href=" <?php echo $doc['url']; ?>"> |
4 |
Download PDF Here |
5 |
</a> |
Lassen Sie uns nun den Link in einen Container einwickeln, damit wir ihn einfach formatieren können. Ich gebe meinem Container die ID 'wp_custom_attachment'. Fühlen Sie sich frei, alles zu verwenden, was Sie möchten. Denken Sie daran, in Ihrem Stylesheet richtig darauf zu verweisen.
Hier ist mein Markup:
1 |
the_content(); |
2 |
$doc = get_post_meta(get_the_ID(), 'wp_custom_attachment', true); |
3 |
<div id="wp_custom_attachment"> |
4 |
<a href="<?php echo $doc['url']; ?>"> |
5 |
Download PDF Here |
6 |
</a> |
7 |
</div><!-- #wp_custom_attachment --> |
Und hier ist mein CSS:
1 |
.wp_custom_attachment { |
2 |
margin: 8px 0 8px 0; |
3 |
border: 1px solid #DDD; |
4 |
background: #EEE; |
5 |
padding: 8px; |
6 |
text-align: center; |
7 |
border-radius: 4px; |
8 |
}
|
Wenn Sie alles richtig geschrieben haben, sollte der Download-Link jetzt folgendermaßen aussehen:



Viel besser, oder? Es ist jetzt so gestylt das enger in das Thema integriert werden. Denken Sie daran, auch die entsprechenden Änderungen an page.php vorzunehmen (da wir Dateianhänge sowohl auf Posts als auch auf Seiten unterstützen).
Herunterladen, sofern verfügbar
Bevor wir fortfahren, müssen wir noch eine kleine Änderung am Code vornehmen, den wir gerade hinzugefügt haben. Im Moment wird der Download-Link bedingungslos angezeigt. Das bedeutet, dass unabhängig davon, ob ein Beitrag tatsächlich eine Datei enthält oder nicht, der Download-Link angezeigt wird.
Im Idealfall möchten wir den Download-Link nur dann anzeigen, wenn eine Datei heruntergeladen werden muss. Als solches brauchen wir eine Bedingung. Insbesondere müssen wir die zugehörigen Post-Metadaten abrufen und feststellen, ob es eine tatsächliche URL für den Dateianhang gibt. In diesem Fall wird der Link angezeigt; sonst werden wir nicht.
In dem Codeblock, den wir gerade zu content-single.php hinzugefügt haben, platzieren Sie eine öffnende if-Anweisung direkt über dem öffnenden wp_custom_attachment-Tag und schließen Sie die Anweisung direkt unter dem schließenden Container-Tag. Im Moment sollte der Code ungefähr so aussehen:
1 |
the_content(); |
2 |
$doc = get_post_meta(get_the_ID(), 'wp_custom_attachment', true); |
3 |
if() { |
4 |
<div id="wp_custom_attachment"> |
5 |
<a href="<?php echo $doc['url']; ?>"> |
6 |
Download PDF Here |
7 |
</a> |
8 |
</div><!-- #wp_custom_attachment --> |
9 |
} // end if |
Wir müssen das Vorhandensein der URL des Dokuments überprüfen. Es gibt eine Reihe von Möglichkeiten, dies zu tun, aber ich überprüfe dies normalerweise anhand des URL-Attributs. Der resultierende Codeblock lautet:
1 |
the_content(); |
2 |
$doc = get_post_meta(get_the_ID(), 'wp_custom_attachment', true); |
3 |
if(strlen(trim($doc['url'])) > 0) { |
4 |
<div id="wp_custom_attachment"> |
5 |
<a href="<?php echo $doc['url']; ?>"> |
6 |
Download PDF Here |
7 |
</a> |
8 |
</div><!-- #wp_custom_attachment --> |
9 |
} // end if |
Zu diesem Zeitpunkt sollte der Download-Link nur angezeigt werden, wenn eine gültige Datei an den Beitrag oder die Seite angehängt ist. Versuch es.
Datei löschen
Zu diesem Zeitpunkt haben wir einige lose Enden aus dem vorherigen Beitrag zusammengebunden und sind bereit, die zum Löschen von Anhängen erforderlichen Funktionen abzuschließen.
Legen Sie die Grundlage
Erinnern Sie sich an den letzten Beitrag, dass, sobald der Benutzer versucht, eine Datei hochzuladen, eine Serialisierungsfunktion ausgelöst wird, die für das tatsächliche Schreiben der Datei auf die Festplatte verantwortlich ist. Als Referenz erfolgt dies in save_custom_meta_data.
Um eine Datei ordnungsgemäß zu löschen, müssen wir den Speicherort der vorhandenen Datei verfolgen und feststellen, ob ein Benutzer tatsächlich das Löschen der Datei angefordert hat oder nicht. Wir machen das mit einer Kombination aus einem Eingabefeld und einem Anker.
Suchen Sie zuerst die Funktion 'wp_custom_attachment', die wir im letzten Beitrag erstellt haben. Hier haben wir das Dateieingabeelement hinzugefügt. Fügen Sie direkt unter dem Eingabeelement den folgenden Code hinzu (die vollständige Funktion wird unten bereitgestellt):
1 |
// Create the input box and set the file's URL as the text element's value
|
2 |
$html .= '<input type="text" id="wp_custom_attachment_url" name="wp_custom_attachment_url" value=" ' . $doc['url'] . '" size="30" />'; |
Wir machen das mit einer Kombination aus einem Eingabefeld und einem Anker. Wir werden dies etwas später im Tutorial bereinigen, aber jetzt wollen wir einen Anker zum Löschen der Datei einführen. Schreiben Sie direkt unter die beiden Codezeilen, die wir gerade hinzugefügt haben, Folgendes:
1 |
$html .= '<a href="javascript:;" id="wp_custom_attachment_delete">' . __('Delete File') . '</a>'; |
Beachten Sie: Wir haben dem Anker eine eindeutige ID gegeben. Dies ist erforderlich, wenn wir den Administrationsbereich für die Behandlung von Benutzerereignissen anschließen. Wenn Sie Ihrem Anker diese ID nicht geben, notieren Sie sich, was Sie zuweisen.
Wir sind noch nicht ganz fertig. Erinnern Sie sich, wie wir die einzelnen Post- und Seitenaufrufe so eingerichtet haben, dass der Download-Link bedingt angezeigt wird? Wir müssen dasselbe für den Löschlink tun. Insbesondere müssen wir den Löschlink nur anzeigen, wenn ein Dokument vorhanden ist. Schließen Sie den Anker auf ähnliche Weise in eine bedingte Anweisung ein, die prüft, ob die URL des Dokuments vorhanden ist:
1 |
// Display the 'Delete' option if a URL to a file exists
|
2 |
if(strlen(trim($doc['url'])) > 0) { |
3 |
$html .= '<a href="javascript:;" id="wp_custom_attachment_delete">' . __('Delete File') . '</a>'; |
4 |
} // end if |
Es ist nichts zu schwer, oder? Um vollständig zu sein, hier ist die volle Funktion, wie sie steht:
1 |
function wp_custom_attachment() { |
2 |
|
3 |
wp_nonce_field(plugin_basename(__FILE__), 'wp_custom_attachment_nonce'); |
4 |
|
5 |
$html = '<p class="description">'; |
6 |
$html .= 'Upload your PDF here.'; |
7 |
$html .= '</p>'; |
8 |
$html .= '<input type="file" id="wp_custom_attachment" name="wp_custom_attachment" value="" size="25" />'; |
9 |
|
10 |
// Grab the array of file information currently associated with the post
|
11 |
$doc = get_post_meta(get_the_ID(), 'wp_custom_attachment', true); |
12 |
|
13 |
// Create the input box and set the file's URL as the text element's value
|
14 |
$html .= '<input type="text" id="wp_custom_attachment_url" name="wp_custom_attachment_url" value=" ' . $doc['url'] . '" size="30" />'; |
15 |
|
16 |
// Display the 'Delete' option if a URL to a file exists
|
17 |
if(strlen(trim($doc['url'])) > 0) { |
18 |
$html .= '<a href="javascript:;" id="wp_custom_attachment_delete">' . __('Delete File') . '</a>'; |
19 |
} // end if |
20 |
|
21 |
echo $html; |
22 |
|
23 |
} // end wp_custom_attachment |
Wir werden diese Funktion ein wenig wiederholen, aber später im Tutorial, aber vorerst testen. Navigieren Sie zunächst zu einem Beitrag ohne Anhang. Sie sollten das Dateieingabefeld und ein leeres Eingabefeld sehen. Nach dem Hochladen einer Datei sollte das Eingabefeld die URL der Datei enthalten, gefolgt von einem Link zum Löschen der Datei.
Aber wir sind noch nicht fertig. Immerhin macht der Löschlink eigentlich nichts.
Verkabelung
Suchen Sie als Nächstes das Verzeichnis 'js' im Themenstamm. Fügen Sie eine neue Datei mit dem Namen custom_attachment.js hinzu. Wir werden für diesen Moment Code schreiben, aber der Zweck der Datei wird es uns ermöglichen, das PDF, das wir an einen Beitrag angehängt haben, tatsächlich zu löschen.
Öffnen Sie danach die Datei functions.php und fügen Sie am Ende der Datei die folgende Funktion hinzu:
1 |
function add_custom_attachment_script() { |
2 |
|
3 |
wp_register_script('custom-attachment-script', get_stylesheet_directory_uri() . '/js/custom_attachment.js'); |
4 |
wp_enqueue_script('custom-attachment-script'); |
5 |
|
6 |
} // end add_custom_attachment_script |
7 |
add_action('admin_enqueue_scripts', 'add_custom_attachment_script'); |
Diese Funktion liest die soeben erstellte JavaScript-Datei und fügt sie auf jeder Verwaltungsseite im WordPress-Backend ein. Das Einreihen und Registrieren von Skripten würde den Rahmen des Lernprogramms sprengen, ich empfehle jedoch, sich darüber zu informieren.
Als nächstes besuchen wir die JavaScript-Datei erneut. Im Allgemeinen sollte der Code Folgendes tun:
- Stellen Sie fest, ob der Löschlink vorhanden ist
- Wenn der Link vorhanden ist, fügen Sie einen benutzerdefinierten Ereignishandler hinzu, der die Texteingabe löscht, die die URL der Datei enthält
- Blenden Sie den Link aus, sobald die Datei zum Löschen markiert wurde
Der Quellcode befindet sich unten und wurde vollständig kommentiert, um zu erklären, was jede Zeile tut:
1 |
jQuery(function($) { |
2 |
|
3 |
// Check to see if the 'Delete File' link exists on the page...
|
4 |
if($('a#wp_custom_attachment_delete').length === 1) { |
5 |
|
6 |
// Since the link exists, we need to handle the case when the user clicks on it...
|
7 |
$('#wp_custom_attachment_delete').click(function(evt) { |
8 |
|
9 |
// We don't want the link to remove us from the current page
|
10 |
// so we're going to stop it's normal behavior.
|
11 |
evt.preventDefault(); |
12 |
|
13 |
// Find the text input element that stores the path to the file
|
14 |
// and clear it's value.
|
15 |
$('#wp_custom_attachment_url').val(''); |
16 |
|
17 |
// Hide this link so users can't click on it multiple times
|
18 |
$(this).hide(); |
19 |
|
20 |
});
|
21 |
|
22 |
} // end if |
23 |
|
24 |
});
|
Zu diesem Zeitpunkt wird die Datei nicht gelöscht, Sie sollten jedoch eine Funktionsansicht haben. Suchen Sie eine Seite, an die eine Datei angehängt ist. Ihre benutzerdefinierte Meta-Box sollte ungefähr so aussehen:

Nach dem Klicken auf den Anker 'Delete Link' sollte das benutzerdefinierte Meta-Feld folgendermaßen aussehen:

Wenn nicht, überprüfen Sie Ihre Debugging-Konsole, um sicherzustellen, dass Sie keine JavaScript-Fehler haben.
Datei löschen
Zu diesem Zeitpunkt haben wir die Datei fast vollständig gelöscht. Dazu müssen wir die Funktion save_custom_meta_data aktualisieren, die wir im ersten Beitrag geschrieben haben. Denken Sie daran, dass die Funktion eine bedingte Überprüfung des Inhalts der $_FILES-Auflistung enthält, die aus der POST-Anforderung stammt. Wenn die Sammlung gefüllt ist, serialisieren wir die Datei.
Da wir versuchen, die Datei zu löschen, sollte die $_FILES-Auflistung keine Daten enthalten, sodass unser gesamter Code in einer else-Klausel enthalten sein muss. Der vollständige Quellcode für die Funktion wird unten bereitgestellt. Die Funktionsweise der Funktion sollte jedoch folgendermaßen aussehen:
- Überprüfen Sie, ob dem Beitrag ein Dokument zugeordnet ist
- Überprüfen Sie, ob das Textfeld zum Verfolgen der URL der Datei leer ist
- Wenn eine Datei vorhanden ist und das Textfeld leer ist, löschen Sie die Datei und aktualisieren Sie die zugehörigen Metadaten
Das muss einfach sein: Wir haben jedem Beitrag ein Textelement gegeben, das die URL zur Datei enthält. Wenn die Datei-URL leer ist, bedeutet dies, dass der Benutzer auf den Link 'Delete File' geklickt hat und das Löschen der Datei anfordert. So können wir genau das erreichen:
1 |
// Grab a reference to the file associated with this post
|
2 |
$doc = get_post_meta($id, 'wp_custom_attachment', true); |
3 |
|
4 |
// Grab the value for the URL to the file stored in the text element
|
5 |
$delete_flag = get_post_meta($id, 'wp_custom_attachment_url', true); |
6 |
|
7 |
// Determine if a file is associated with this post and if the delete flag has been set (by clearing out the input box)
|
8 |
if(strlen(trim($doc['url'])) > 0 && strlen(trim($delete_flag)) == 0) { |
9 |
|
10 |
// Attempt to remove the file. If deleting it fails, print a WordPress error.
|
11 |
if(unlink($doc['file'])) { |
12 |
|
13 |
// Delete succeeded so reset the WordPress meta data
|
14 |
update_post_meta($id, 'wp_custom_attachment', null); |
15 |
update_post_meta($id, 'wp_custom_attachment_url', ''); |
16 |
|
17 |
} else { |
18 |
wp_die('There was an error trying to delete your file.'); |
19 |
} // end if/el;se |
20 |
|
21 |
} // end if |
Beachten Sie nach dem Löschen der Datei, dass wir auch die Post-Metadaten aktualisieren müssen, indem wir den Wert des Anhangs sowie den URL-Wert des Anhangs leeren. In dem seltsamen Fall, dass die Datei nicht gelöscht wird, wird eine einfache Fehlermeldung angezeigt. Die erweiterte Fehlerbehandlung geht über den Rahmen dieses Beitrags hinaus.
Wie versprochen, ist hier die vollständige Serialisierungsfunktion:
1 |
function save_custom_meta_data($id) { |
2 |
|
3 |
/* --- security verification --- */
|
4 |
if(!wp_verify_nonce($_POST['wp_custom_attachment_nonce'], plugin_basename(__FILE__))) { |
5 |
return $id; |
6 |
} // end if |
7 |
|
8 |
if(defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { |
9 |
return $id; |
10 |
} // end if |
11 |
|
12 |
if(!current_user_can('edit_page', $id)) { |
13 |
return $id; |
14 |
} // end if |
15 |
/* - end security verification - */
|
16 |
|
17 |
// Make sure the file array isn't empty
|
18 |
if(!empty($_FILES['wp_custom_attachment']['name'])) { |
19 |
|
20 |
// Setup the array of supported file types. In this case, it's just PDF.
|
21 |
$supported_types = array('application/pdf'); |
22 |
|
23 |
// Get the file type of the upload
|
24 |
$arr_file_type = wp_check_filetype(basename($_FILES['wp_custom_attachment']['name'])); |
25 |
$uploaded_type = $arr_file_type['type']; |
26 |
|
27 |
// Check if the type is supported. If not, throw an error.
|
28 |
if(in_array($uploaded_type, $supported_types)) { |
29 |
|
30 |
// Use the WordPress API to upload the file
|
31 |
$upload = wp_upload_bits($_FILES['wp_custom_attachment']['name'], null, file_get_contents($_FILES['wp_custom_attachment']['tmp_name'])); |
32 |
|
33 |
if(isset($upload['error']) && $upload['error'] != 0) { |
34 |
wp_die('There was an error uploading your file. The error is: ' . $upload['error']); |
35 |
} else { |
36 |
add_post_meta($id, 'wp_custom_attachment', $upload); |
37 |
update_post_meta($id, 'wp_custom_attachment', $upload); |
38 |
} // end if/else |
39 |
|
40 |
} else { |
41 |
wp_die("The file type that you've uploaded is not a PDF."); |
42 |
} // end if/else |
43 |
|
44 |
} else { |
45 |
|
46 |
// Grab a reference to the file associated with this post
|
47 |
$doc = get_post_meta($id, 'wp_custom_attachment', true); |
48 |
|
49 |
// Grab the value for the URL to the file stored in the text element
|
50 |
$delete_flag = get_post_meta($id, 'wp_custom_attachment_url', true); |
51 |
|
52 |
// Determine if a file is associated with this post and if the delete flag has been set (by clearing out the input box)
|
53 |
if(strlen(trim($doc['url'])) > 0 && strlen(trim($delete_flag)) == 0) { |
54 |
|
55 |
// Attempt to remove the file. If deleting it fails, print a WordPress error.
|
56 |
if(unlink($doc['file'])) { |
57 |
|
58 |
// Delete succeeded so reset the WordPress meta data
|
59 |
update_post_meta($id, 'wp_custom_attachment', null); |
60 |
update_post_meta($id, 'wp_custom_attachment_url', ''); |
61 |
|
62 |
} else { |
63 |
wp_die('There was an error trying to delete your file.'); |
64 |
} // end if/el;se |
65 |
|
66 |
} // end if |
67 |
|
68 |
} // end if/else |
69 |
|
70 |
} // end save_custom_meta_data |
71 |
add_action('save_post', 'save_custom_meta_data'); |
Inzwischen haben Sie eine voll funktionsfähige benutzerdefinierte Meta-Box. Versuche es.
Aufräumen
Wir müssen noch eine letzte kleine Änderung vornehmen, um unsere Benutzeroberfläche zu vervollständigen. Erinnern Sie sich an die Texteingabe, die wir zuvor im Lernprogramm hinzugefügt haben und die für die Pflege der URL der Datei verantwortlich ist? Wir können das als versteckt markieren - es gibt keinen Grund, warum der Benutzer es sehen muss. Die JavaScript-Quelle verwendet es weiterhin ordnungsgemäß und sein Wert wird in der Serialisierungsfunktion gelesen.
Die endgültige Funktion wp_custom_attachment sollte folgendermaßen aussehen:
1 |
function wp_custom_attachment() { |
2 |
|
3 |
wp_nonce_field(plugin_basename(__FILE__), 'wp_custom_attachment_nonce'); |
4 |
|
5 |
$html = '<p class="description">'; |
6 |
$html .= 'Upload your PDF here.'; |
7 |
$html .= '</p>'; |
8 |
$html .= '<input type="file" id="wp_custom_attachment" name="wp_custom_attachment" value="" size="25" />'; |
9 |
|
10 |
// Grab the array of file information currently associated with the post
|
11 |
$doc = get_post_meta(get_the_ID(), 'wp_custom_attachment', true); |
12 |
|
13 |
// Create the input box and set the file's URL as the text element's value
|
14 |
$html .= '<input type="hidden" id="wp_custom_attachment_url" name="wp_custom_attachment_url" value=" ' . $doc['url'] . '" size="30" />'; |
15 |
|
16 |
// Display the 'Delete' option if a URL to a file exists
|
17 |
if(strlen(trim($doc['url'])) > 0) { |
18 |
$html .= '<a href="javascript:;" id="wp_custom_attachment_delete">' . __('Delete File') . '</a>'; |
19 |
} // end if |
20 |
|
21 |
echo $html; |
22 |
|
23 |
} // end wp_custom_attachment |
Diese beiden Beiträge enthielten viele Informationen. Es gibt eine Reihe von vorgefertigten Lösungen - seien es Plugins, Themes oder andere Add-Ons -, die solche Funktionen integrieren können. Ein guter Entwickler ist jedoch auch ein Wissen darüber, wann eine Drittanbieterlösung verwendet und wann eine eigene entwickelt werden muss.
Wenn Sie professionell mit WordPress arbeiten, ist es außerdem wichtig, die API zu verstehen. Hoffentlich hat diese Serie dazu beigetragen, viel von dem zu zeigen, was durch die Nutzung der Kernfunktionen von WordPress erreicht werden kann.