Integrarea WordPress Self-Hosted
Cum publică Contento articolele direct pe site-ul tău WordPress prin REST API, ce cereri trimite și cum poți reproduce manual cu curl pentru debugging.
1. Cum funcționează
Pentru a publica un articol, Contento face două cereri HTTP către WordPress REST API:
- Încarcă imaginea principală către
/wp-json/wp/v2/mediași salvează ID-ul returnat. - Creează articolul printr-un POST către
/wp-json/wp/v2/posts, folosind ID-ul imaginii cafeatured_media.
Dacă ai nevoie să confirmi că integrarea trimite cererile corect, poți reproduce manual exact aceste apeluri folosind exemplele de mai jos.
2. Autentificare
Toate cererile folosesc Basic Auth peste HTTPS, cu o Application Password generată din WordPress (Utilizatori → Profil → Application Passwords). Nu se folosește parola obișnuită a contului.
Authorization: Basic <base64(username:app_password)>
Pentru exemplele care urmează, configurează două variabile în shell:
SITE="https://example.com"
AUTH=$(printf '%s' 'WP_USERNAME:APP_PASSWORD' | base64)
3. Pasul 1 — Încarcă imaginea principală
Imaginea se urcă pe WordPress ca atașament. WordPress răspunde cu un JSON care conține câmpul id — îl vei folosi în pasul următor.
curl -i -X POST "$SITE/wp-json/wp/v2/media" \
-H "Authorization: Basic $AUTH" \
-H "Content-Type: image/jpeg" \
-H 'Content-Disposition: attachment; filename="test.jpg"' \
-H "User-Agent: Contento/1.0" \
--data-binary "@$HOME/test.jpg"
Atenție la câteva detalii ușor de greșit:
Content-Typetrebuie să corespundă cu tipul real al fișierului (image/pngpentru PNG, etc.). Verifică cufile image.jpg.- Argumentul
--data-binarytrebuie să înceapă cu@— altfel curl trimite literalmente șirul de caractere, nu conținutul fișierului. - Tilde-ul (
~) nu este expandat în interiorul argumentului@— folosește$HOMEsau o cale absolută.
Răspuns de succes (HTTP 201):
{
"id": 5738,
"source_url": "https://example.com/wp-content/uploads/2026/05/test.jpg",
"media_type": "image",
...
}
4. Pasul 2 — Creează articolul cu imagine principală
Înlocuiește MEDIA_ID cu id-ul obținut la pasul anterior:
curl -i -X POST "$SITE/wp-json/wp/v2/posts" \
-H "Authorization: Basic $AUTH" \
-H "Content-Type: application/json" \
-H "User-Agent: Contento/1.0" \
-d '{
"title": "Test featured image",
"content": "<p>Body</p>",
"status": "publish",
"slug": "test-featured-image",
"featured_media": MEDIA_ID
}'
Un răspuns HTTP 201 cu "featured_media": <același id> și clasa has-post-thumbnail în class_list confirmă că WordPress a legat corect imaginea de articol.
5. Câmpurile pe care le trimite Contento
Pentru fiecare articol publicat, Contento construiește un body de forma:
{
"title": "Titlul articolului",
"content": "<html-ul articolului>",
"status": "publish",
"excerpt": "Meta description",
"slug": "slug-articol",
"categories": [123],
"tags": [456, 789],
"featured_media": 999,
"meta": {
"_yoast_wpseo_focuskw": "cuvânt cheie",
"rank_math_focus_keyword": "cuvânt cheie",
"_aioseo_keywords": "cuvânt cheie"
}
}
Câmpul featured_media apare doar dacă încărcarea imaginii a reușit. Câmpul meta conține cuvântul cheie focus pentru cele trei plugin-uri SEO populare (Yoast, Rank Math, All in One SEO).
6. Probleme comune
Imaginea nu apare pe pagina articolului
Dacă răspunsul pasului 2 conține "featured_media" și clasa has-post-thumbnail, dar imaginea tot nu se vede în browser, problema este la tema WordPress, nu la integrare. Template-ul temei trebuie să apeleze funcția the_post_thumbnail() în layout-ul single post — multe teme custom sau cele construite cu page builder-e nu o apelează implicit, sau ascund imaginea în spatele unui toggle din Customizer.
Un semn revelator: imaginea apare în share-urile pe social media (OG / Twitter Card) și în structured data Yoast, dar nu pe pagină — pentru că plugin-urile SEO citesc featured_media direct, fără să depindă de template.
HTTP 400 rest_upload_no_data
Curl a trimis un body gol — fișierul nu există la calea specificată sau ai uitat prefixul @ înainte de cale. Verifică cu ls -la că fișierul există și are dimensiune nenulă.
HTTP 500 rest_upload_sideload_error
WordPress nu poate detecta tipul fișierului — fie Content-Type nu corespunde conținutului real (ex: trimiți un PNG cu image/jpeg), fie body-ul este o secvență de caractere arbitrară (uitat prefixul @ la --data-binary).
Răspuns HTML în loc de JSON
Dacă răspunsul începe cu <!doctype html> sau <html>, un firewall sau plugin de securitate (Wordfence, iThemes Security, etc.) blochează /wp-json/. Verifică regulile firewall-ului și whitelist-ul pluginului de securitate.
HTTP 401 sau 403
Application Password greșit sau dezactivat. Generează una nouă din Utilizatori → Profil → Application Passwords și actualizează integrarea în dashboard. Atenție: spațiile dintre grupurile de caractere fac parte din parolă.
7. Contact
Dacă întâmpini probleme cu integrarea WordPress Self-Hosted, scrie-ne la [email protected] cu URL-ul site-ului și pașii pe care i-ai încercat.