WordPress oferuje bogate API, które umożliwia programistom zdalne zarządzanie treścią na stronie. W tym artykule przedstawię kroki, jakie należy podjąć, aby dodać nowy post do WordPressa za pomocą ich API, wykorzystamy skrypt oparty na PHP i Curl. Gotowy kod przykładu znajduje się w repozytorium GitHub: https://github.com/kamilwyremski/wordpress-create-post-by-api
Przygotowanie środowiska
Na początku w panelu administracyjnym naszej strony opartej o WordPress musimy stworzyć hasło aplikacji. Przechodzimy do zakładki Użytkownicy > Profil. Wyszukujemy pole „Nowa nazwa hasła aplikacji”, wpisujemy dowolną nazwę i klikamy na „Dodaj nowe hasło aplikacji”. Zostanie nam wyświetlone pole z nowym hasłem aplikacji.
Teraz w katalogu z naszym projektem tworzymy plik konfiguracyjny .env
, który zawierać będzie dane uwierzytelniające oraz adres domeny WordPressa. Poniżej znajdziesz przykład pliku .env
:
WORDPRESS_DOMAIN=http://twoja-domena.pl
WORDPRESS_USERNAME=twoja-nazwa-uzytkownika
WORDPRESS_PASSWORD=wygenerowane-haslo
Gdzie WORDPRESS_DOMAIN to adres URL naszego bloga, WORDPRESS_USERNAME to nazwa którą wpisaliśmy w polu „Nowa nazwa hasła aplikacji” a hasła to hasło które zostało nam wyświetlone po dodanu hasła aplikacji.
Klasa WordPressAPI
Następnie, tworzymy klasę WordPressApi
w pliku wordpress-api.class.php. Poniżej jej szkielet:
class WordPressApi
{
private $domain;
private $username;
private $password;
public function __construct(string $domain, string $username, string $password)
{
$this->domain = $domain;
$this->username = $username;
$this->password = $password;
}
// Metoda dodająca media do WordPressa
public function addMedia(string $url, string $filename = '')
{
// ... (kod metody)
}
// Metoda dodająca tag do postu
public function addTag(string $tag)
{
// ... (kod metody)
}
// Metoda zamieniająca linki do obrazków w treści posta
private function replaceImageLinks(array $matches)
{
// ... (kod metody)
}
// Metoda dodająca post do WordPressa
public function addArticle(string $title, string $body = '', string $lid = '', array $tags = [], string $thumbnail_id = null)
{
// ... (kod metody)
}
}
W metodzie konstruktora, która inicjalizuje obiekt WordPressApi
ustawiajamy domenę, nazwę użytkownika i hasło ze zmiennych środowiskowych.
Metoda addMedia
Ta metoda służy do dodawania obrazków do WordPressa. Jest ona nam potrzebna jeśli chcemy później móc dodać miniaturkę do wpisu. Poniżej jej kod:
function addMedia(string $url, string $filename = ''){
$image_data = file_get_contents($url);
if ($image_data === false) {
throw new \Exception('Error fetching image from URL.');
}
$boundary = uniqid();
if(!$filename){
$filename = pathinfo(basename($url), PATHINFO_FILENAME);
}
$filename = mb_strtolower($filename);
$data = "--$boundary\r\n" .
"Content-Disposition: form-data; name=\"file\"; filename=\"".$filename.".jpg\"\r\n" .
"Content-Type: image/jpeg\r\n\r\n" .
"$image_data\r\n" .
"--$boundary--\r\n";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->domain . '/wp-json/wp/v2/media');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Basic '. base64_encode($this->username . ':' . $this->password),
'Content-Type: multipart/form-data; boundary=' . $boundary,
'Content-Length: ' . strlen($data),
]);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($ch);
if ($response === false) {
throw new \Exception(curl_error($ch));
}
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_code == 201) {
return json_decode($response ,true);
} else {
throw new \Exception($http_code);
}
}
Metoda ta przyjmuje URL obrazu i opcjonalny argument z nazwą pliku. Pobiera obraz z podanego URL, tworzy dane w formacie wieloczęściowym (multipart form-data) i wysyła żądanie POST do endpointa WordPress API odpowiedzialnego za dodawanie mediów. Następnie zwraca dane o dodanym obrazie. Wykorzystujemy do zapytań CURL.
Jeśli używasz innych formatów obrazków niż .jpg zmień odpowiednio Content Type.
Autoryzujemy żądanie dodając odpowiedni nagłówek (tak będziemy robić także w pozostałych zapytaniach do API): 'Authorization: Basic '. base64_encode($this->username . ':' . $this->password)
Metoda addTag
Ta metoda służy do dodawania tagów do WordPressa. Oto jej kod:
function addTag(string $tag){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->domain . '/wp-json/wp/v2/tags');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Basic '. base64_encode($this->username . ':' . $this->password),
'Content-Type: application/json; charset=utf-8',
]);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'name' => trim($tag)
]));
$response = curl_exec($ch);
curl_close($ch);
if ($response) {
$new_tag = json_decode($response, true);
if(!empty($new_tag['id'])){
return $new_tag;
}else{
throw new \Exception('Error creating tag');
}
} else {
throw new \Exception('Error creating tag');
}
}
Metoda ta jako parametr przyjmuje nazwę tagu. Wysyła żądanie POST do endpointa WordPress API odpowiedzialnego za dodawanie tagów. Następnie zwraca dane o dodanym tagu.
Metoda replaceImageLinks
To metoda prywatna, która jest używana do zamiany linków do obrazków w treści posta. Każdy obrazek w treści jest dodawany jako media do Wodpressa. Nie jest to niezbędne do działania skryptu ale może być bardzo przydatne jeśli w treści wstawisz linki do obrazków. Oto jej kod:
private function replaceImageLinks(array $matches) {
$imageData = $this->addMedia($matches[1]);
return str_replace($matches[1], $imageData['guid']['rendered'], $matches[0]);
}
Metoda addArticle
To główna metoda w naszej klasie. Tworzy ona nowy artykuł na podstawie parametrów które przyjmuje: tytuł artykułu, treść (w HTML), wprowadzenie, tablica tagów i ID miniaturki.
Wywołuje wcześniej opisaną metodę replaceImageLinks
do zamiany linków do obrazków w treści posta.
Poniżej kod tej metody:
function addArticle(string $title, string $body = '', string $lid = '', array $tags = [], string $thumbnail_id = null){
$pattern = '/<img[^>]+src=[\'"]([^\'"]+)[\'"][^>]*>/';
$body = preg_replace_callback($pattern, [$this, 'replaceImageLinks'], $body);
$postfields = json_encode([
'status' => 'publish',
'tags' => $tags,
'title' => $title,
'content' => $body,
'excerpt' => $lid,
'featured_media' => $thumbnail_id
]);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $this->domain . '/wp-json/wp/v2/posts');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Basic '. base64_encode($this->username . ':' . $this->password),
'Content-Type: application/json; charset=utf-8',
]);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
$response = curl_exec($ch);
curl_close($ch);
if ($response) {
$post = json_decode($response, true);
if (!empty($post['id'])) {
return $post;
} else {
throw new \Exception($post['message']);
}
}else{
throw new \Exception('Error communicating with WordPress API.');
}
}
Funkcja ta wysyła żądanie POST do endpointa WordPress API odpowiedzialnego za dodawanie postów. Pola są wysyłane w JSON. Ustawiamy status posta na publish (opublikowany), ale możesz to zmienić na draft (szkic).
Te metody wspólnie tworzą funkcjonalność klasy WordPressApi
, umożliwiając dodawanie treści, mediów i tagów do WordPressa za pomocą API. Spójrzmy teraz jak je wywoływać.
Formularz wysyłki artykułu
Szkielet strony
Tworzymy szkielet strony www z formularzem wysyłki artykułu. Oto przykładowy kod w pliku index.php
:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Add post to WordPress</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css">
</head>
<body>
<div class="container mt-5">
<h1 class="mb-4">Add post to WordPress</h1>
<form method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>">
<div class="mb-3">
<label for="title" class="form-label">Title:</label>
<input type="text" name="title" required class="form-control" id="title">
</div>
<div class="mb-3">
<label for="lid" class="form-label">LID:</label>
<textarea name="lid" rows="2" required class="form-control" id="lid"></textarea>
</div>
<div class="mb-3">
<label for="content" class="form-label">Content (in HTML):</label>
<textarea name="content" rows="4" required class="form-control" id="content"></textarea>
</div>
<div class="mb-3">
<label for="tags" class="form-label">Tags (enter after comma):</label>
<input type="text" name="tags" class="form-control" id="tags">
</div>
<div class="mb-3">
<label for="thumb" class="form-label">Link to thumb:</label>
<input type="url" name="thumb" class="form-control" id="thumb">
</div>
<button type="submit" class="btn btn-primary">Send</button>
</form>
</div>
</body>
</html>
Wykorzystujemy tutaj Bootstrap ale oczywiście nie jest to wymagane.
Wczytywanie zmiennych środowiskowych
W tym celu można użyć gotowych bibliotek. Jako że nie chciałem być od nich zależny w tym małym projekcie stworzyłem skrypt do czytania pliku .env i ustawiania zmiennych środowiskowych. Oto jego kod (dodałem go na samej górze pliku index.php
):
<?php
$envFilePath = __DIR__ . '/.env';
if (!file_exists($envFilePath)) {
die('.env file not found.');
}
$envContent = file_get_contents($envFilePath);
$lines = explode("\n", $envContent);
foreach ($lines as $line) {
$line = trim($line);
if (!empty($line) && strpos($line, '=') !== false) {
list($key, $value) = explode('=', $line, 2);
$key = trim($key);
$value = trim($value);
putenv("$key=$value");
$_ENV[$key] = $value;
}
}
require_once('wordpress-api.class.php');
$wordpressApi = new WordPressApi(getenv('WORDPRESS_DOMAIN'), getenv('WORDPRESS_USERNAME'), getenv('WORDPRESS_PASSWORD'));
?>
Załączamy w nim także naszą klasę wordpressAPI i następnie tworzymy obiekt WordPressApi
na podstawie danych konfiguracyjnych z pliku .env
.
Odbiór danych z formularza i tworzenie artykułu
Na koniec zostało nam sprawdzenie czy formularz został wysłany i wywołanie odpowiednich metod z klasy WordPressApi. Chcemy dodać media, tagi i na końcu sam artykuł. Oto kod (załączam go w body dokumentu nad formularzem):
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST" and !empty($_POST['title']) and !empty($_POST['lid']) and !empty($_POST['content'])) {
$thumbnail_id = null;
if (!empty($_POST['thumb'])) {
try {
$thumbnail_id = $wordpressApi->addMedia($_POST['thumb'], $_POST['title'])['id'];
} catch (\Exception $e) {
echo ('<p>Error sending image: ' . $e->getMessage() . '</p>');
}
}
$tags = [];
if (!empty($_POST['tags'])) {
$new_tags = explode(',', $_POST['tags']);
foreach ($new_tags as $tag) {
try {
$tags[] = $wordpressApi->addTag($tag)['id'];
echo ('<p>Tag created successfully: ' . $new_tag_name . '</p>');
} catch (\Exception $e) {
echo ('<p>Error creating tag: ' . $e->getMessage() . '</p>');
}
}
}
try {
$post = $wordpressApi->addArticle($_POST['title'], $_POST['content'], $_POST['lid'], $tags, $thumbnail_id);
echo('<p>You have successfully added an article. Post ID: ' . $post['id'] . '</p>');
} catch (\Exception $e) {
echo('<p>Error: ' . $e->getMessage() . '</p>');
}
}
?>
Warunek if ($_SERVER["REQUEST_METHOD"] == "POST" ...)
sprawdza, czy formularz został wysłany metodą POST i zawiera wymagane pola.
Jeśli użytkownik podał link do obrazu ($_POST['thumb']
), próbujemy dodać to media do WordPressa za pomocą metody addMedia
z klasy WordPressApi
. Jeśli dodawanie obrazu zakończy się sukcesem, otrzymamy jego ID.
Jeśli użytkownik podał tagi ($_POST['tags']
), oddzielone od siebie przecinkami, dzielimy je na pojedyncze tagi. Każdy tag próbujemy dodać do WordPressa za pomocą metody addTag
z klasy WordPressApi
.
Następnie próbujemy dodać artykuł do WordPressa, wywołując metodę addArticle
z klasy WordPressApi
. W przypadku sukcesu, wyświetlamy komunikat o pomyślnym dodaniu artykułu wraz z ID nowego posta.
Podsumowanie
Mam nadzieję, że ten wpis pomoże Wam w tworzeniu postów na WordPressie za pomocą swojego skryptu PHP. Gotowy kod znajduję się w repozytorium https://github.com/kamilwyremski/wordpress-create-post-by-api
Pamiętaj, żeby po skopiowaniu utworzyć własny plik .env
z adresem URL, loginem i hasłem aplikacji.
Miłego kodowania!