~/icsd.ir — bash
SYSTEM_ONLINE

📡 فصل ۱۱: REST API وردپرس

REST API وردپرس امکان می‌ده داده‌های سایت رو از خارج وردپرس بخونی و بنویسی - برای اپ موبایل، SPA با React، یا یکپارچگی با سرویس‌های دیگه.

REST API وردپرس امکان می‌ده داده‌های سایت رو از خارج وردپرس بخونی و بنویسی – برای اپ موبایل، SPA با React، یا یکپارچگی با سرویس‌های دیگه.

🌐 REST API چیست؟

از وردپرس ۴.۷ به بعد، یه REST API کامل به هسته اضافه شده. این API به‌صورت پیش‌فرض در آدرس /wp-json/ در دسترسه.

تست کن!

توی مرورگر برو به: https://yoursite.com/wp-json/

یه JSON بزرگ می‌بینی که همه route ها رو لیست کرده.

کاربردهای REST API

  • ساخت اپ موبایل با Flutter/React Native (مرتبط با پروژه آپادانا!)
  • ساخت SPA با React/Vue که از وردپرس به‌عنوان backend استفاده کنه
  • یکپارچگی با سرویس‌های دیگه (CRM، ERP)
  • انتشار خودکار محتوا
  • گزارش‌گیری و آنالیز
📱

برای آپادانا

می‌تونی از REST API برای ساخت اپ Flutter استفاده کنی – دقیقاً همون کاری که داری انجام می‌دی! استک: WordPress + WooCommerce + REST API + Flutter.

📍 endpoint های پیش‌فرض

نوشته‌ها

متد endpoint عملکرد
GET /wp-json/wp/v2/posts لیست نوشته‌ها
GET /wp-json/wp/v2/posts/{id} یک نوشته
POST /wp-json/wp/v2/posts افزودن نوشته
PUT /wp-json/wp/v2/posts/{id} ویرایش نوشته
DELETE /wp-json/wp/v2/posts/{id} حذف نوشته

سایر منابع

  • /wp-json/wp/v2/pages – برگه‌ها
  • /wp-json/wp/v2/categories – دسته‌ها
  • /wp-json/wp/v2/tags – برچسب‌ها
  • /wp-json/wp/v2/users – کاربران
  • /wp-json/wp/v2/media – رسانه
  • /wp-json/wp/v2/comments – دیدگاه‌ها

برای CPT

اگه CPT با show_in_rest => true ثبت شده باشه، خودکار توی API هست:

/wp-json/wp/v2/{post_type}

پارامترهای پرکاربرد

query parameters
// تعداد و صفحه
GET /wp-json/wp/v2/posts?per_page=20&page=2

// مرتب‌سازی
GET /wp-json/wp/v2/posts?orderby=date&order=desc

// جستجو
GET /wp-json/wp/v2/posts?search=وردپرس

// فیلتر دسته
GET /wp-json/wp/v2/posts?categories=5

// فیلد های خاص
GET /wp-json/wp/v2/posts?_fields=id,title,excerpt

// تعبیه شده (embed)
GET /wp-json/wp/v2/posts?_embed

🔐 احراز هویت

خوندن نوشته‌های منتشرشده نیاز به احراز نداره. ولی نوشتن، خوندن پیش‌نویس و اطلاعات کاربر نیاز به authentication داره.

۱. Application Passwords (پیش‌فرض از 5.6)

راحت‌ترین روش! توی پنل کاربر:

  1. برو به کاربران → پروفایل خودت
  2. پایین صفحه «Application Passwords» رو پیدا کن
  3. یه نام بذار (مثل «اپ آپادانا») و کلیک کن «Add New»
  4. یه کلید ۲۴ کاراکتری دریافت می‌کنی – یک‌بار نمایش داده می‌شه
  5. توی header درخواست استفاده کن:
cURL
curl --user "username:xxxx xxxx xxxx xxxx xxxx xxxx" 
  https://yoursite.com/wp-json/wp/v2/posts?status=draft

۲. JWT Authentication

برای اپ‌های موبایل – با افزونه JWT Authentication for WP REST API:

  1. افزونه رو نصب کن
  2. توی wp-config.php این رو اضافه کن:
wp-config.php
define('JWT_AUTH_SECRET_KEY', 'your-super-secret-key-here-min-32-chars');
define('JWT_AUTH_CORS_ENABLE', true);

۳. توی .htaccess:

.htaccess
RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]

گرفتن توکن

login
POST /wp-json/jwt-auth/v1/token
Content-Type: application/json

{
    "username": "admin",
    "password": "your-password"
}

// Response:
{
    "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6...",
    "user_email": "admin@site.com",
    "user_nicename": "admin",
    "user_display_name": "محمدعلی"
}

استفاده از توکن

authenticated request
GET /wp-json/wp/v2/posts?status=draft
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6...

🛠 ساخت endpoint سفارشی

register_rest_route

custom endpoint
add_action( 'rest_api_init', function () {
    register_rest_route( 'icsd/v1', '/products/featured', array(
        'methods'             => 'GET',
        'callback'            => 'get_featured_products',
        'permission_callback' => '__return_true',  // عمومی
    ) );
} );

function get_featured_products( $request ) {
    $args = array(
        'post_type'      => 'icsd_product',
        'posts_per_page' => 10,
        'meta_query'     => array(
            array(
                'key'   => '_featured',
                'value' => '1',
            ),
        ),
    );
    
    $query = new WP_Query( $args );
    $products = array();
    
    foreach ( $query->posts as $post ) {
        $products[] = array(
            'id'        => $post->ID,
            'title'     => $post->post_title,
            'excerpt'   => $post->post_excerpt,
            'thumbnail' => get_the_post_thumbnail_url( $post->ID, 'medium' ),
            'link'      => get_permalink( $post->ID ),
            'price'     => get_post_meta( $post->ID, '_price', true ),
        );
    }
    
    return rest_ensure_response( $products );
}

endpoint با parameter

با parameter
add_action( 'rest_api_init', function () {
    register_rest_route( 'icsd/v1', '/products/(?P<id>d+)', array(
        'methods'  => 'GET',
        'callback' => 'get_single_product',
        'args'     => array(
            'id' => array(
                'validate_callback' => function( $param ) {
                    return is_numeric( $param );
                },
            ),
        ),
        'permission_callback' => '__return_true',
    ) );
} );

function get_single_product( $request ) {
    $id = (int) $request['id'];
    $post = get_post( $id );
    
    if ( ! $post || $post->post_type !== 'icsd_product' ) {
        return new WP_Error( 'not_found', 'محصول یافت نشد', array( 'status' => 404 ) );
    }
    
    return rest_ensure_response( array(
        'id'    => $post->ID,
        'title' => $post->post_title,
        'price' => get_post_meta( $post->ID, '_price', true ),
    ) );
}

// تست:
// GET /wp-json/icsd/v1/products/123

endpoint با POST

POST endpoint
add_action( 'rest_api_init', function () {
    register_rest_route( 'icsd/v1', '/contact', array(
        'methods'             => 'POST',
        'callback'            => 'handle_contact_form',
        'permission_callback' => '__return_true',
        'args'                => array(
            'name'    => array(
                'required'          => true,
                'sanitize_callback' => 'sanitize_text_field',
            ),
            'email'   => array(
                'required'          => true,
                'sanitize_callback' => 'sanitize_email',
                'validate_callback' => function( $value ) {
                    return is_email( $value );
                },
            ),
            'message' => array(
                'required'          => true,
                'sanitize_callback' => 'sanitize_textarea_field',
            ),
        ),
    ) );
} );

function handle_contact_form( $request ) {
    $name    = $request->get_param( 'name' );
    $email   = $request->get_param( 'email' );
    $message = $request->get_param( 'message' );
    
    // ارسال ایمیل
    $sent = wp_mail(
        get_option( 'admin_email' ),
        'فرم تماس از: ' . $name,
        $message,
        array( "From: $name <$email>" )
    );
    
    if ( $sent ) {
        return rest_ensure_response( array(
            'success' => true,
            'message' => 'پیام ارسال شد!',
        ) );
    }
    
    return new WP_Error( 'send_failed', 'ارسال ناموفق', array( 'status' => 500 ) );
}

🛡 permission_callback

تابعی که چک می‌کنه آیا کاربر اجازه فراخوانی این endpoint رو داره یا نه.

permission examples
// عمومی
'permission_callback' => '__return_true',

// فقط کاربر لاگین
'permission_callback' => function() {
    return is_user_logged_in();
},

// فقط ادمین
'permission_callback' => function() {
    return current_user_can( 'manage_options' );
},

// دسترسی خاص
'permission_callback' => function() {
    return current_user_can( 'edit_posts' );
},

// با بررسی پارامتر
'permission_callback' => function( $request ) {
    $post_id = $request['id'];
    return current_user_can( 'edit_post', $post_id );
},

📲 مصرف API

JavaScript (Fetch API)

fetch.js
// خوندن نوشته‌ها
fetch( 'https://yoursite.com/wp-json/wp/v2/posts?per_page=5' )
    .then( response => response.json() )
    .then( posts => {
        posts.forEach( post => {
            console.log( post.title.rendered );
        } );
    } );

// با احراز هویت
fetch( 'https://yoursite.com/wp-json/wp/v2/posts', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ' + token,
    },
    body: JSON.stringify( {
        title:   'نوشته از API',
        content: 'محتوا...',
        status:  'publish',
    } ),
} )
.then( res => res.json() )
.then( data => console.log( data ) );

Flutter (Dart)

api_service.dart
import 'package:http/http.dart' as http;
import 'dart:convert';

class ApiService {
  final String baseUrl = 'https://yoursite.com/wp-json/wp/v2';
  String? token;
  
  // دریافت محصولات
  Future<List<dynamic>> getProducts() async {
    final response = await http.get(
      Uri.parse('$baseUrl/icsd_product?per_page=20'),
    );
    
    if (response.statusCode == 200) {
      return jsonDecode(response.body);
    } else {
      throw Exception('خطا در دریافت محصولات');
    }
  }
  
  // ورود
  Future<void> login(String username, String password) async {
    final response = await http.post(
      Uri.parse('https://yoursite.com/wp-json/jwt-auth/v1/token'),
      body: {'username': username, 'password': password},
    );
    
    if (response.statusCode == 200) {
      final data = jsonDecode(response.body);
      token = data['token'];
    }
  }
  
  // ساخت سفارش (با authentication)
  Future<Map<String, dynamic>> createOrder(Map<String, dynamic> orderData) async {
    final response = await http.post(
      Uri.parse('$baseUrl/orders'),
      headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer $token',
      },
      body: jsonEncode(orderData),
    );
    
    return jsonDecode(response.body);
  }
}

Python

api_client.py
import requests

# Application Password
auth = ('username', 'xxxx xxxx xxxx xxxx xxxx xxxx')

# لیست نوشته‌ها
response = requests.get(
    'https://yoursite.com/wp-json/wp/v2/posts',
    params={'per_page': 10, 'status': 'publish'},
    auth=auth
)
posts = response.json()

# ساخت نوشته
new_post = {
    'title': 'نوشته از پایتون',
    'content': '<p>این نوشته با Python ساخته شده!</p>',
    'status': 'publish',
    'categories': [3],
}

response = requests.post(
    'https://yoursite.com/wp-json/wp/v2/posts',
    json=new_post,
    auth=auth
)
print(response.json())

🎯 مثال‌های کاربردی

متوسط

جستجوی پیشرفته

search endpoint
register_rest_route( 'icsd/v1', '/search', array(
    'methods'  => 'GET',
    'callback' => 'icsd_search',
    'args'     => array(
        'q' => array( 'required' => true ),
    ),
    'permission_callback' => '__return_true',
) );

function icsd_search( $request ) {
    $query = sanitize_text_field( $request['q'] );
    
    $results = new WP_Query( array(
        's'              => $query,
        'post_type'      => array( 'post', 'page', 'icsd_product' ),
        'posts_per_page' => 20,
    ) );
    
    $output = array();
    foreach ( $results->posts as $post ) {
        $output[] = array(
            'title'     => $post->post_title,
            'type'      => $post->post_type,
            'link'      => get_permalink( $post->ID ),
            'thumbnail' => get_the_post_thumbnail_url( $post->ID, 'thumbnail' ),
        );
    }
    
    return rest_ensure_response( $output );
}

📝 خلاصه فصل

  • REST API در /wp-json/ در دسترسه
  • Application Password راحت‌ترین احراز هویت
  • JWT برای اپ‌های موبایل بهتره
  • register_rest_route برای endpoint سفارشی
  • permission_callback همیشه ست کن – حتی __return_true
  • برای CPT خودت show_in_rest => true بذار

نمایش سایت

رنگ سایت
حالت نمایش
اندازهٔ متن
خوانایی

این تنظیمات فقط روی مرورگر شما ذخیره می‌شود.