Mit der REST-API arbeiten
So rufst du die easy-svg/v1-Routen hinter dem Icons-Panel auf: Anmeldung, Rechte, jede Route mit Feldern, Fehlern und funktionierenden Beispielen.
Tutorial · Easy SVG
Easy SVG registriert sieben REST-Routen im Namensraum easy-svg/v1. Das Icons-Panel im Backend nutzt sie, um die Einstellungen zu lesen und zu speichern und um Icons hinzuzufügen, umzubenennen, neu zu zeichnen und zu löschen. Dieses Tutorial zeigt dir, wie du dieselben Routen selbst aufrufst, aus dem Terminal, aus einem Deployment-Skript oder aus deinem eigenen Admin-JavaScript, und was jede Route annimmt und antwortet.
easy_svg_rename_icon(), easy_svg_update_icon_markup()), wenn dein Code ohnehin in WordPress läuft.Die Routen auf einen Blick
| Route | Methode | Was sie tut | Referenz |
|---|---|---|---|
/wp-json/easy-svg/v1/settings | GET, POST | Liest oder speichert die Funktionsschalter und die Größengrenze | rest-settings |
/wp-json/easy-svg/v1/library | GET | Listet die gespeicherten Icons, optional durchsucht | rest-library |
/wp-json/easy-svg/v1/library/add | POST | Fügt ein Icon aus SVG-Markup hinzu | rest-library-add |
/wp-json/easy-svg/v1/library/media | POST | Macht aus SVGs der Mediathek Icons | rest-library-media |
/wp-json/easy-svg/v1/library/rename | POST | Ändert den sichtbaren Namen eines Icons | rest-library-rename |
/wp-json/easy-svg/v1/library/replace | POST | Gibt einem Icon eine neue Zeichnung | rest-library-replace |
/wp-json/easy-svg/v1/library/delete | POST | Löscht ein Icon endgültig | rest-library-delete |
Alle werden auf rest_api_init von easy_svg_panel_rest() in includes/panel.php registriert. Die Routen sind immer da, egal ob der Schalter für die Icon-Bibliothek an ist oder nicht (mehr dazu unter Stolperfallen).
Anmeldung
Jede Route braucht einen angemeldeten Benutzer. Dafür gibt es zwei Wege.
WordPress bringt seit 5.6 Anwendungspasswörter mit. Sie sind genau dafür gedacht: Ein Skript spricht mit einer Website, ohne das echte Passwort des Kontos zu kennen.
Passwort anlegen
Geh im Backend auf Benutzer > Profil (oder bearbeite den Benutzer, als der das Skript handeln soll) und scroll zu Anwendungspasswörter. Gib einen Namen ein, etwa "Icon-Deploy", klick auf Neues Anwendungspasswort hinzufügen und kopier das angezeigte Passwort. Es wird nur einmal gezeigt.
Einen Administrator nehmen
Der Benutzer braucht die Berechtigung manage_options (siehe Berechtigungen). Mit dem Anwendungspasswort eines Redakteurs bekommst du auf jeder Route eine 403.
Als Basic Auth senden
Gib Benutzername und Passwort samt Leerzeichen mit -u an curl. Lass die Anführungszeichen stehen, wegen der Leerzeichen.
curl https://example.com/wp-json/easy-svg/v1/settings \
-u admin:'abcd efgh ijkl mnop qrst uvwx'
Anwendungspasswörter funktionieren nur über HTTPS, außer der Umgebungstyp der Website ist local. Über reines HTTP bietet WordPress sie gar nicht erst an.
Code, der im Browser eines angemeldeten Admins läuft, hat das Login-Cookie schon dabei. WordPress akzeptiert dieses Cookie für die REST-API aber nur, wenn die Anfrage zusätzlich eine Nonce für die Aktion wp_rest im Header X-WP-Nonce mitschickt. Ohne Nonce gilt die Anfrage als abgemeldet.
Die Nonce erzeugst du in PHP mit wp_create_nonce( 'wp_rest' ) und gibst sie an dein Skript weiter. Auf dem Icons-Bildschirm selbst macht Easy SVG das schon: window.EasySvgPanelData.nonce und window.EasySvgPanelData.restRoot sind die Werte, die das Panel benutzt.
Am einfachsten ist wp.apiFetch: Hängt dein Skript von wp-api-fetch ab, richtet WordPress Basis-URL und Nonce dafür ein, und du fasst den Header nie selbst an.
add_action( 'admin_enqueue_scripts', 'myaddon_enqueue_icon_tools' );
function myaddon_enqueue_icon_tools( $hook_suffix ) {
if ( 'tools_page_myaddon-icons' !== $hook_suffix ) {
return;
}
wp_enqueue_script(
'myaddon-icon-tools',
plugins_url( 'js/icon-tools.js', __FILE__ ),
array( 'wp-api-fetch' ),
'1.0.0',
true
);
}
Nimmst du stattdessen reines fetch(), gibst du die Nonce selbst mit:
wp_add_inline_script(
'myaddon-icon-tools',
'window.myaddonRest = ' . wp_json_encode(
array(
'root' => esc_url_raw( rest_url( 'easy-svg/v1/' ) ),
'nonce' => wp_create_nonce( 'wp_rest' ),
)
) . ';',
'before'
);
So sieht eine gescheiterte Anmeldung aus:
| Situation | Status | Code |
|---|---|---|
| Keine Zugangsdaten, oder Cookie ohne Nonce | 401 | rest_forbidden |
Angemeldet, aber ohne manage_options | 403 | rest_forbidden |
| Cookie mit falscher oder abgelaufener Nonce | 403 | rest_cookie_invalid_nonce |
| Falsches Anwendungspasswort | 401 | ein Anmeldefehler aus dem WordPress-Core |
Berechtigungen
Jede Route, ob lesend oder schreibend, nutzt denselben Permission-Callback, easy_svg_panel_rest_permission(). Er ist eine Zeile lang:
function easy_svg_panel_rest_permission(): bool {
return current_user_can( 'manage_options' );
}
Daraus folgen drei Dinge:
- Es ist
manage_options, nichtedit_theme_options. Der Icon-Beitragstyp selbst verlangtEASY_SVG_ICON_CAP(edit_theme_options), die REST-Routen verlangen mehr. Wer Theme-Optionen bearbeiten, aber keine Optionen verwalten darf, kommt nicht an sie heran. - Die Berechtigungen der Panel-Tabs zählen hier nicht. Ein Add-on kann einem Tab eine eigene Berechtigung geben (siehe
easy_svg_panel_tab_capabilities()). Das entscheidet nur, welche Tabs und Menüeinträge jemand sieht. Die REST-Routen prüfen trotzdemmanage_options. - Auch die lesenden Routen sind nur für Admins.
GET /settingsundGET /librarysind nicht öffentlich, weil die Bibliotheksantwort das Markup jedes Icons enthält.
In einem Multisite-Netzwerk wird manage_options auf der Website geprüft, an die die Anfrage geht. Ein Website-Administrator kann die Routen also auf seiner eigenen Website nutzen.
Wie eine Anfrage verarbeitet wird
Die Reihenfolge zu kennen hilft, denn welcher Fehler zurückkommt, hängt davon ab, welcher Schritt abgelehnt hat.
WordPress prüft die Argumente, bevor es die Berechtigung prüft. Eine Anfrage, der ein Pflichtfeld fehlt, antwortet mit 400, auch wenn niemand angemeldet ist. Lies eine 400 also nicht als "meine Zugangsdaten stimmen".
Jeder POST-Handler liest den JSON-Body und sonst nichts. Jeder beginnt mit $request->get_json_params(). WordPress füllt das nur, wenn die Anfrage Content-Type: application/json mitschickt. Das hat eine fiese Folge: Die Schemaprüfung in Schritt C schaut an jeder Stelle, an der ein Parameter stehen kann (JSON-Body, Formular-Body, Query-String), der Handler aber nur in den JSON-Body. Eine Anfrage kann die Prüfung also bestehen und trotzdem leer beim Handler ankommen:
# Besteht das Schema (id=42 steht im Query-String),
# aber der Handler sieht keinen JSON-Body, liest id als 0 und antwortet 404.
curl -X POST 'https://example.com/wp-json/easy-svg/v1/library/delete?id=42' \
-u admin:'abcd efgh ijkl mnop qrst uvwx'
Die Lösung ist immer dieselbe: Schick die Felder als JSON, mit dem Header.
curl -X POST https://example.com/wp-json/easy-svg/v1/library/delete \
-u admin:'abcd efgh ijkl mnop qrst uvwx' \
-H 'Content-Type: application/json' \
-d '{"id":42}'
Die einzige Ausnahme ist GET /library, das search wie jede GET-Route aus dem Query-String liest.
WordPress wandelt die Typen um, bevor der Handler läuft. Weil die Routen ihre Argumente deklarieren, bereinigt WordPress die JSON-Werte auf den deklarierten Typ. Aus "id":"42" wird die Zahl 42, aus "icons":"false" das Boolean false. Ein Wert, der sich nicht umwandeln lässt ("id":"abc", "icons":"vielleicht", "max_mb":2.5), wird mit 400 rest_invalid_param abgelehnt.
Fehlerantworten
Jeder Fehler, ob von WordPress oder von Easy SVG, hat die übliche WordPress-Form:
{
"code": "easy_svg_add_failed",
"message": "That name cannot be turned into an icon name. Use letters and numbers.",
"data": {
"status": 422
}
}
Schemafehler von WordPress bringen zusätzlich ein Objekt params mit, das das Feld nennt:
{
"code": "rest_invalid_param",
"message": "Invalid parameter(s): id",
"data": {
"status": 400,
"params": {
"id": "id must be greater than or equal to 1"
}
}
}
Entscheide anhand von code und data.status. Zeig message den Leuten, aber werte den Text nie aus: Er ist übersetzt.
_locale=user an den Query-String, etwa /wp-json/easy-svg/v1/library/add?_locale=user. Das Icons-Panel macht das bei jedem Aufruf.Die Bibliotheksantwort
Sechs der Routen antworten mit demselben Objekt: der aktuellen Icon-Liste. Sie wird von easy_svg_panel_library_payload() gebaut und immer direkt aus der Datenbank gelesen, nie aus dem Icon-Cache. Sie zeigt also schon den Schreibvorgang, den du gerade gemacht hast.
Die Icons, älteste zuerst (sortiert nach Beitrags-ID), höchstens EASY_SVG_PANEL_LIBRARY_MAX (500). Jeder Eintrag hat id (Zahl, die ID des esw_icon-Beitrags), slug (Text, der Name, den Icon-Block und easy_svg_icon() verwenden), label (Text, der sichtbare Name) und content (Text, das gespeicherte Markup, schon bereinigt und gehärtet). Immer eine Liste, nie ein Objekt.
Ohne Suche: wie viele veröffentlichte Icons die Website hat, das können mehr sein, als in items stehen. Mit Suche: die Zahl der zurückgegebenen Treffer, also nie mehr als 500.
Ob die Liste bei 500 abgeschnitten wurde. Ohne Suche ist es true, wenn total größer ist als die Zahl der Einträge. Mit Suche ist es true, sobald die Suche alle 500 Plätze gefüllt hat, auch eine Suche mit genau 500 Treffern meldet also true.
Blättern gibt es nicht. Icons nach dem 500. erreichst du über diese Routen nicht, nur eine engere Suche (search) zeigt sie.
Einstellungen: GET und POST /settings
Liest oder speichert die drei Werte auf dem Tab Einstellungen des Panels. Vollständige Referenz: rest-settings.
GET nimmt keine Argumente und gibt easy_svg_settings() zurück. POST führt den JSON-Body mit dem Gespeicherten zusammen, schickt das Ergebnis durch easy_svg_sanitize_settings(), speichert es und gibt die Einstellungen so zurück, wie sie jetzt sind. Ein Schlüssel, den du weglässt, behält seinen gespeicherten Wert, ein ausdrückliches false schaltet eine Funktion ab.
Ob SVG-Dateien in die Mediathek hochgeladen werden dürfen. Nimmt true, false und die Formen, die WordPress umwandelt (1, 0, "true", "false").
Ob die Icon-Bibliothek eingeschaltet ist: der Beitragstyp esw_icon, die Easy-SVG-Sammlung für den Icon-Block und der Shortcode [easy_svg_icon].
Das größte SVG, das der Sanitizer verarbeitet, in Megabyte. Das Schema lehnt alles unter 1 ab (400 rest_invalid_param) und alles, was keine ganze Zahl ist. Eine Obergrenze im Schema gibt es absichtlich nicht: Ein Wert über der Obergrenze aus easy_svg_max_mb_ceiling() (20, außer der Filter easy_svg_max_mb_ceiling hebt sie an) wird auf diese Grenze gesetzt und gespeichert, nicht abgelehnt.
# Lesen
curl https://example.com/wp-json/easy-svg/v1/settings \
-u admin:'abcd efgh ijkl mnop qrst uvwx'
# Icon-Bibliothek einschalten, den Rest in Ruhe lassen
curl -X POST https://example.com/wp-json/easy-svg/v1/settings \
-u admin:'abcd efgh ijkl mnop qrst uvwx' \
-H 'Content-Type: application/json' \
-d '{"icons":true}'
const settings = await wp.apiFetch( { path: '/easy-svg/v1/settings' } );
// 50 MB anfragen. Mit der Standardgrenze von 20 sagt die Antwort 20.
const saved = await wp.apiFetch( {
path: '/easy-svg/v1/settings',
method: 'POST',
data: { max_mb: 50 },
} );
if ( saved.max_mb < 50 ) {
console.info( `Auf die Obergrenze gesetzt: ${ saved.max_mb } MB` );
}
| Status | Code | Wann |
|---|---|---|
| 400 | rest_invalid_param | max_mb unter 1 oder keine ganze Zahl, ein Schalter, der kein Boolean ist |
Gut zu wissen:
- Änderungen wirken ab der nächsten Anfrage. Upload- und Icon-Funktion werden eingehängt, wenn
easy-svg.phplädt. Die Anfrage, dieicons: truespeichert, läuft also noch ohne Icon-Bibliothek. Die Antwort zeigt den neuen Wert trotzdem schon. - Unbekannte Schlüssel fallen weg. Der Sanitizer gibt nur
svg_upload,iconsundmax_mbzurück. - Ein POST als Formular tut stillschweigend nichts. Der Handler sieht einen leeren JSON-Body, führt nichts zusammen und antwortet 200 mit den unveränderten Einstellungen.
Icons auflisten: GET /library
Vollständige Referenz: rest-library.
Parameter im Query-String. Grenzt die Liste auf Icons ein, deren sichtbarer Name oder Slug den Begriff enthält. Das Markup wird nie durchsucht. Der Begriff wird mit sanitize_text_field() bereinigt und getrimmt, ein leerer Begriff liefert die ganze Bibliothek.
curl 'https://example.com/wp-json/easy-svg/v1/library?search=pfeil' \
-u admin:'abcd efgh ijkl mnop qrst uvwx'
const term = 'pfeil';
const library = await wp.apiFetch( {
path: `/easy-svg/v1/library?search=${ encodeURIComponent( term ) }`,
} );
library.items.forEach( ( icon ) => {
console.log( icon.slug, icon.label );
} );
if ( library.truncated ) {
console.warn( 'Nur die ersten 500 Icons kamen zurück. Such enger.' );
}
Außer der Anmeldung hat diese Route keinen eigenen Fehler. Für den Titel nutzt die Suche die normale Beitragssuche von WordPress, für den Slug eine eigene LIKE-Abfrage (easy_svg_icon_ids_by_slug_like()). Beide Treffermengen werden zusammengeführt, bevor die Grenze von 500 greift.
Icon hinzufügen: POST /library/add
Speichert ein Icon aus SVG-Markup. Vollständige Referenz: rest-library-add.
Das SVG-Markup als Text. Es läuft durch den Sanitizer der Website, durch dieselben Größen- und Komplexitätsgrenzen wie ein Upload und danach durch eine Härtung, die alles Aktive entfernt, weil der Icon-Block das Ergebnis direkt ins HTML schreibt. Fehlt es ganz: 400 rest_missing_callback_param. Ist es da, aber leer oder nur Leerraum: 422 mit der Meldung für "empty".
Der sichtbare Name. Im Schema optional, in der Praxis Pflicht: Ohne Label oder mit einem, aus dem sich kein Slug machen lässt, scheitert das Hinzufügen mit 422 und der Meldung für "bad_name". Das Label wird mit sanitize_text_field() bereinigt, Tags fallen also weg. Der Slug entsteht daraus mit sanitize_title() und muss mit ^[a-z0-9] beginnen, danach Buchstaben, Ziffern, _ oder - enthalten und mit einem Buchstaben oder einer Ziffer enden. Ein Label nur in einer Schrift, die WordPress nicht in ASCII umwandeln kann (Kyrillisch, Japanisch und so weiter), ergibt keinen gültigen Slug und wird abgelehnt. Umlaute sind kein Problem, sie werden umgeschrieben.
Ist der Slug schon vergeben, macht WordPress ihn eindeutig (aus herz wird herz-2). Die Antwort sagt es dir: added.slug ist der Slug, den das Icon bekommen hat, added.wanted der, den das Label wollte.
curl -X POST https://example.com/wp-json/easy-svg/v1/library/add \
-u admin:'abcd efgh ijkl mnop qrst uvwx' \
-H 'Content-Type: application/json' \
-d '{"label":"Herz","markup":"<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 21l-8-8a5 5 0 0 1 8-6 5 5 0 0 1 8 6z"/></svg>"}'
Um eine Datei von der Platte zu schicken, lass jq das JSON bauen, dann sind die Anführungszeichen richtig maskiert:
jq -n --arg label 'Herz' --rawfile markup herz.svg \
'{label: $label, markup: $markup}' |
curl -X POST https://example.com/wp-json/easy-svg/v1/library/add \
-u admin:'abcd efgh ijkl mnop qrst uvwx' \
-H 'Content-Type: application/json' \
--data-binary @-
async function myaddonAddIcon( label, markup ) {
try {
const result = await wp.apiFetch( {
path: '/easy-svg/v1/library/add?_locale=user',
method: 'POST',
data: { label, markup },
} );
if ( result.added.slug !== result.added.wanted ) {
console.info(
`"${ result.added.wanted }" war vergeben, das Icon heißt "${ result.added.slug }".`
);
}
return result.added;
} catch ( error ) {
// error ist der JSON-Body: { code, message, data: { status } }
if ( 'easy_svg_add_failed' === error.code ) {
window.alert( error.message );
return null;
}
throw error;
}
}
Jede Ablehnung durch den Speicher antwortet mit 422 easy_svg_add_failed. Nur die Meldung unterscheidet die Gründe, ein maschinenlesbares Feld für den Grund gibt es nicht. Die Prüfungen laufen in dieser Reihenfolge, und die erste, die scheitert, bestimmt die Meldung (aus easy_svg_panel_add_message(), hier im englischen Original):
| Grund | Meldung |
|---|---|
| Die Sanitizer-Bibliothek ist nicht geladen | The sanitizer is unavailable, so nothing was stored. Reinstall the plugin to restore it. |
| Kein Label, oder eines ohne gültigen Slug | That name cannot be turned into an icon name. Use letters and numbers. |
| Markup leer oder nur Leerraum | That SVG is empty, so there was nothing to store. |
Markup länger als easy_svg_max_bytes() | That SVG is larger than the size allowed in Settings. |
Zu viele Processing Instructions oder use-Elemente (easy_svg_svg_too_complex()) | That SVG has too many parts to be read safely. |
| Der Sanitizer hat abgelehnt, oder es blieb nichts Zeichenbares übrig | That is not an SVG the sanitizer accepts. |
Der Datenbank-Schreibvorgang scheiterte, oder im gespeicherten Beitrag steht kein svg | That SVG could not be stored: it arrived without a drawing, or the write was refused. |
Der Handler hat außerdem einen Zweig 409 easy_svg_no_store für den Fall, dass der Icon-Speicher fehlt. Er kann nicht auslösen: Er prüft function_exists( 'easy_svg_add_icon' ), und includes/icon-manager.php, wo diese Funktion steht, wird bei jeder Anfrage geladen. Bau keine Logik darauf auf.
Aus der Mediathek hinzufügen: POST /library/media
Macht aus SVG-Dateien, die schon Anhänge sind, Icons. Du schickst Anhang-IDs, nie Dateiinhalte: Der Server liest jede Datei selbst von der Platte. Vollständige Referenz: rest-library-media.
Anhang-IDs, mindestens 1 und höchstens EASY_SVG_MEDIA_MAX_IDS (25). Die Grenze steht im Schema der Route, ein Client kann sie also mit einer OPTIONS-Anfrage auslesen. Jeder Eintrag muss eine ganze Zahl sein (oder ein Zahlen-String, den WordPress umwandelt). Die IDs werden in der gesendeten Reihenfolge verarbeitet, Doppelte werden nicht entfernt: Dieselbe ID zweimal ergibt zwei Icons (stern und stern-2).
Der Titel des Anhangs wird zum Label des Icons. Jede Datei läuft durch denselben Sanitizer, dieselben Grenzen und dieselbe Härtung wie bei /library/add, denn ein SVG, das hochgeladen wurde, bevor Easy SVG aktiv war, wurde vielleicht nie bereinigt.
curl -X POST https://example.com/wp-json/easy-svg/v1/library/media \
-u admin:'abcd efgh ijkl mnop qrst uvwx' \
-H 'Content-Type: application/json' \
-d '{"ids":[101,102,103]}'
// Der Server nimmt 25 IDs pro Anfrage. Mehr schickst du in Stücken, wie das Panel.
async function myaddonImportMedia( ids ) {
const chunkSize = 25;
const report = [];
for ( let start = 0; start < ids.length; start += chunkSize ) {
const result = await wp.apiFetch( {
path: '/easy-svg/v1/library/media',
method: 'POST',
data: { ids: ids.slice( start, start + chunkSize ) },
} );
report.push( ...result.report );
}
return report.filter( ( row ) => 'added' !== row.state );
}
Eine Anfrage wird entweder als Ganzes abgelehnt oder antwortet 200 mit einer report-Zeile pro ID. Eine schlechte Datei hält die anderen nie auf.
| Status | Code | Wann |
|---|---|---|
| 400 | rest_missing_callback_param | Nirgends in der Anfrage ein ids |
| 400 | rest_invalid_param | ids leer, mehr als 25, oder ein Eintrag, der keine ganze Zahl ist |
| 400 | easy_svg_no_ids | ids hat das Schema bestanden, steht aber nicht im JSON-Body (als Query-String oder Formularfeld gesendet) |
Das eigene 400 easy_svg_too_many des Handlers ("Choose at most 25 files at a time.") ist über REST nicht erreichbar: maxItems im Schema lehnt eine längere Liste vorher ab. Der Zweig 409 easy_svg_no_store ist aus demselben Grund wie bei /library/add unerreichbar.
Pro Zeile ist state einer dieser Werte:
| State | Bedeutung |
|---|---|
added | Gespeichert. Die Zeile hat zusätzlich slug und wanted, und ihr id ist jetzt die ID des neuen Icons. |
not_found | Kein Beitrag mit dieser ID (oder eine ID von 0 oder kleiner). label ist dann leer. |
not_svg | Der MIME-Typ des Anhangs ist nicht image/svg+xml, oder der Sanitizer hat die Datei abgelehnt. |
no_file | Die Datei ist auf diesem Server nicht lesbar, meist weil die Mediathek in einen Cloud-Speicher ausgelagert ist. |
bad_name, empty, too_large, too_complex, not_saved, no_sanitizer | Dieselben Ablehnungen wie bei /library/add, mit denselben Meldungen. Ein Titel, aus dem kein Slug wird, ergibt bad_name. |
Icon umbenennen: POST /library/rename
Ändert den sichtbaren Namen und sonst nichts. Der Slug bleibt, weil Themes, Shortcodes und gespeicherte Icon-Blöcke darauf verweisen. Vollständige Referenz: rest-library-rename.
Die Beitrags-ID des Icons, wie items[].id sie meldet. Mindestens 1.
Der neue Name. Wird mit sanitize_text_field() bereinigt, bleibt nichts übrig (nur Leerzeichen oder nur Tags wie <br>), wird die Umbenennung abgelehnt. Anders als bei /library/add muss der neue Name nicht als Slug taugen.
curl -X POST https://example.com/wp-json/easy-svg/v1/library/rename \
-u admin:'abcd efgh ijkl mnop qrst uvwx' \
-H 'Content-Type: application/json' \
-d '{"id":42,"label":"Herz (gefüllt)"}'
const library = await wp.apiFetch( {
path: '/easy-svg/v1/library/rename',
method: 'POST',
data: { id: 42, label: 'Herz (gefüllt)' },
} );
| Status | Code | Meldung |
|---|---|---|
| 400 | rest_missing_callback_param / rest_invalid_param | id oder label fehlt, oder id unter 1 |
| 404 | easy_svg_no_icon | Icon not found. (kein Beitrag, oder einer, der kein esw_icon ist) |
| 422 | easy_svg_bad_label | An icon needs a name. |
| 500 | easy_svg_rename_failed | The icon could not be renamed. |
Geschrieben wird über die öffentliche Funktion easy_svg_rename_icon(). Sie schaltet kses für dieses eine Update ab (sonst würde der SVG-Inhalt für einen Administrator ohne unfiltered_html entfernt) und leert die zwischengespeicherte Icon-Liste, damit der Editor den neuen Namen sofort zeigt.
Zeichnung eines Icons ersetzen: POST /library/replace
Gibt einem vorhandenen Icon neues Markup und behält Name und Slug, damit jede Seite, die es nutzt, die neue Zeichnung zeigt. Vollständige Referenz: rest-library-replace.
Die Beitrags-ID des Icons. Mindestens 1.
Das neue SVG-Markup. Wird genau wie bei /library/add geprüft: Sanitizer, Größengrenze, Komplexitätsgrenze, Härtung.
jq -n --argjson id 42 --rawfile markup herz-v2.svg \
'{id: $id, markup: $markup}' |
curl -X POST https://example.com/wp-json/easy-svg/v1/library/replace \
-u admin:'abcd efgh ijkl mnop qrst uvwx' \
-H 'Content-Type: application/json' \
--data-binary @-
const library = await wp.apiFetch( {
path: '/easy-svg/v1/library/replace',
method: 'POST',
data: {
id: 42,
markup: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M2 2h20v20H2z"/></svg>',
},
} );
| Status | Code | Meldung |
|---|---|---|
| 400 | rest_missing_callback_param / rest_invalid_param | id oder markup fehlt, oder id unter 1 |
| 404 | easy_svg_no_icon | Icon not found. |
| 422 | easy_svg_replace_refused | That file is not an SVG this library can use. |
Die 422 deckt jedes andere Ergebnis von easy_svg_update_icon_markup() ab: leeres Markup, eine Ablehnung durch Sanitizer oder Grenzen, einen fehlenden Sanitizer und einen gescheiterten Datenbank-Schreibvorgang. Die Meldung spricht in all diesen Fällen von der Datei, auch wenn die Datei in Ordnung war und nur das Schreiben scheiterte.
Icon löschen: POST /library/delete
Löscht ein Icon endgültig. Vollständige Referenz: rest-library-delete.
Die Beitrags-ID des Icons. Mindestens 1. Löschen lässt sich nur ein Beitrag vom Typ esw_icon, jede andere ID, etwa eine Seite oder ein Anhang, antwortet mit 404, und nichts wird angefasst.
curl -X POST https://example.com/wp-json/easy-svg/v1/library/delete \
-u admin:'abcd efgh ijkl mnop qrst uvwx' \
-H 'Content-Type: application/json' \
-d '{"id":42}'
async function myaddonDeleteIcon( icon ) {
const sure = window.confirm(
`"${ icon.label }" löschen? Jede Seite mit easy-svg/${ icon.slug } zeigt danach nichts mehr.`
);
if ( ! sure ) {
return null;
}
return wp.apiFetch( {
path: '/easy-svg/v1/library/delete',
method: 'POST',
data: { id: icon.id },
} );
}
| Status | Code | Meldung |
|---|---|---|
| 400 | rest_missing_callback_param / rest_invalid_param | id fehlt oder liegt unter 1 |
| 404 | easy_svg_no_icon | Icon not found. |
wp_delete_post( $id, true ) gelöscht und landet nicht im Papierkorb. Seiten, Templates und Icon-Blöcke, die den Slug nutzen, zeigen danach nichts mehr an, ohne Fehlermeldung. Der Handler prüft auch nicht, was wp_delete_post() zurückgegeben hat: Eine 200 heißt also "das war ein Icon, und das Löschen wurde versucht". Brauchst du Gewissheit, schau in items der Antwort.Rezept: ersetzen statt einen "-2"-Zwilling anlegen
Fügst du ein Icon hinzu, dessen Name vergeben ist, bekommst du herz-2 neben herz. Wolltest du eigentlich eine neue Zeichnung für herz, bietet das Icons-Panel den Tausch an, und du kannst dasselbe mit drei Aufrufen: hinzufügen, den abweichenden Slug bemerken, das Original ersetzen und die Kopie löschen.
async function myaddonUpsertIcon( label, markup ) {
const result = await wp.apiFetch( {
path: '/easy-svg/v1/library/add',
method: 'POST',
data: { label, markup },
} );
const { id: newId, slug, wanted } = result.added;
if ( slug === wanted ) {
return result; // Der Name war frei, sonst ist nichts zu tun.
}
const original = result.items.find( ( icon ) => icon.slug === wanted );
if ( ! original ) {
return result; // Das Original liegt jenseits der ersten 500 Icons.
}
await wp.apiFetch( {
path: '/easy-svg/v1/library/replace',
method: 'POST',
data: { id: original.id, markup },
} );
return wp.apiFetch( {
path: '/easy-svg/v1/library/delete',
method: 'POST',
data: { id: newId },
} );
}
Das Markup wird zweimal geprüft (beim Hinzufügen und beim Ersetzen). Das ist in Ordnung: Was beim ersten Mal durchkam, kommt auch beim zweiten Mal durch, außer der Titel des Original-Icons ergibt keinen Slug (siehe den Hinweis beim Ersetzen).
Stolperfallen
- JSON oder gar nichts. Jeder POST-Handler liest nur
get_json_params(). OhneContent-Type: application/jsonsind die Felder für den Handler unsichtbar, obwohl sie die Prüfung bestanden haben:/settingsantwortet 200 und ändert nichts,/library/addlehnt mit "bad_name" ab,/library/rename,/library/replaceund/library/deleteantworten 404. - 400 vor 401. WordPress prüft die Argumente vor der Berechtigung. Eine fehlerhafte Anfrage ohne Zugangsdaten bekommt eine 400, keine 401.
- Der Icon-Schalter sperrt die Routen nicht. Alle sieben Routen funktionieren auch bei ausgeschalteter Icon-Bibliothek. Icons, die du dann hinzufügst, sind echte
esw_icon-Beiträge und tauchen auf, sobald der Schalter an ist. Die Antwort 409easy_svg_no_storein den Handlern für add und media ist unerreichbar. - Die zwischengespeicherte Icon-Liste kann Schreibvorgängen bei ausgeschaltetem Schalter hinterherhinken. Die Hooks, die den Cache beim Speichern und Löschen leeren (
save_post_esw_icon,deleted_post), werden nur bei eingeschalteter Icon-Bibliothek registriert./library/renameund/library/replaceleeren den Cache selbst,/library/addund/library/deletenicht. Die REST-Liste betrifft das nicht (sie liest die Datenbank), abereasy_svg_icon()und der Icon-Block lesen den Cache, und der lebt bis zu einem Tag. - Einstellungen wirken ab der nächsten Anfrage, nicht in der, die sie gespeichert hat.
- 500 Icons sind die Decke jeder Antwort. Kein Blättern. Achte auf
truncated. - Ein Fehlercode, viele Gründe.
easy_svg_add_failedundeasy_svg_replace_refusedtragen den Grund nur in der übersetztenmessage. Werte sie nicht aus. Brauchst du den Grund, prüf vorher selbst oder ruf die PHP-Funktionen auf, die mit einem Zustandswort antworten. - Labels können HTML-Entities enthalten. Bei
/library/mediaist das Label der Titel des Anhangs, so wieget_the_title()ihn nach denthe_title-Filtern liefert (typografische Anführungszeichen werden zu’und Ähnlichem). Escape Labels bei der Ausgabe und vergleich sie nicht Byte für Byte mit dem, was du in der Mediathek getippt hast. - Löschen ist endgültig. Kein Papierkorb, keine Revision, keine Warnung vor Seiten, die den Slug noch nutzen.
- Intern heißt intern. Routennamen, Felder und Codes können sich mit jedem Release ändern. Pack deine Aufrufe in eine kleine eigene Client-Funktion, dann ist eine Änderung eine einzige Korrektur.
Siehe auch
easy-svg/v1/settingseasy-svg/v1/libraryeasy-svg/v1/library/addeasy-svg/v1/library/mediaeasy-svg/v1/library/renameeasy-svg/v1/library/replaceeasy-svg/v1/library/deleteeasy_svg_panel_rest_permission()easy_svg_panel_library_payload()easy_svg_rename_icon()easy_svg_update_icon_markup()EASY_SVG_PANEL_LIBRARY_MAXEASY_SVG_MEDIA_MAX_IDS- Ein Add-on bauen
- Entwickler-Überblick