اضافه کردن سیستم اختصاصی ری‌اکت همراه با روتر به وردپرس
ﺯﻣﺎﻥ ﻣﻄﺎﻟﻌﻪ: 4 دقیقه

اضافه کردن سیستم اختصاصی ری‌اکت همراه با روتر به وردپرس

توی آموزش امروز قرار هست یاد بگیریم که چطور میشه یک سیستم اختصاصی و کامل ریکت رو همراه با روتر و همینطور Material UI به وردپرس اضافه کنیم. یعنی طوری بشه که اگر یک آدرس رو فراخوانی کردیم، توسط ریکت بارگذاری بشه و روت های پس از اون هم توسط ریکت روتر، بصورت SPA رندر بشن. این کار رو قراره با نوشتن یک پلاگین در وردپس انجام بدیم.

پیش نیاز درک ادامه مقاله، آشنایی نسبی شما با پلاگین نویسی در وردپرس، Webpack و همینطور React هست.

در وهله اول، باید یک پلاگین در وردپرس ایجاد کنیم. پس در فولدر plugins موجود در wp-content، یک فولدر بنام wp-react ایجاد میکنم (قراره از این اسم برای پروژه و پلاگینمون استفاده کنیم)
یک فایل با نام wp-react.php در این فولدر ایجاد میکنیم و کدهای زیر که معرف یک پلاگین در وردپرس هست رو داخلش می نویسیم:

<?php
/*
Plugin Name: WP-React
Plugin URI:
Description:
Author: Hamed Niroomand
Version: 1.0
*/

با نوشتن دستورات زیر، به نوعی یک روت اختصاصی در وردپرس ایجاد میکنیم

define("WP_REACT_PLUGIN_PATH", __DIR__);
define("WP_REACT_PLUGIN_URI", plugin_dir_url(__FILE__));

add_action('init', 'handle_routes');

function handle_routes()
{
    $request_uri = $_SERVER['REQUEST_URI'];
    $exploded_request = explode("/", $request_uri);
    if ($exploded_request[0] === "" and $exploded_request[1] === "wp-react") {
        include WP_REACT_PLUGIN_PATH . "/templates/index.php";
        exit();
    }
}

دستور اخیر به وردپرس می فهماند که اگر آدرس درخواست وارد شده به سایت با عبارت wp-react شروع شد، از داخل فولدر templates داخل همین پلاگین، فایل index.php را رندر کند.

قبل از اینکه بریم و ببینیم محتویات فایل index.php چی هست، یک فولدر بنام resources در templates درست میکنیم و نیازمندی های ریکت رو با npm در آن نصب و کانفیگ میکنیم:

npm init --y
npm i webpack webpack-cli @babel/core babel-loader @babel/preset-react @babel/plugin-transform-runtime css-loader style-loader -D
npm i react react-dom react-router-dom @material-ui/core @material-ui/icons

مرحله بعد، مرحله کانفیگ webpack هست.
در فایل webpack.config.js کانفیگ های زیر رو قرار میدیم:

const path = require("path");
module.exports = {
    mode: "production",
    entry: "./src/index.js",
    output: {
        path: path.resolve(__dirname, "dist"),
        filename: "app.bundle.js",
    },
    module: {
        rules: [
            {
                test: /\.jsx?$/,
                exclude: /node_modules/,
                use: {
                    loader: "babel-loader",
                    options: {
                        cacheDirectory: true,
                        presets: ["@babel/preset-react"],
                        plugins: ["@babel/plugin-transform-runtime"],
                    },
                },
            },
            {
                test: /\.css$/,
                use: ["style-loader", "css-loader"],
            },
        ],
    },
    resolve: {
        extensions: [".js", ".jsx"],
    },
};

این کانفیگ بیانگر اینه که webpack، فایل index.js موجود در فولدر src، که کدهای ریکت در آن نوشته میشود را در فولدری به نام dist و با نام app.bundle.js باندل کنه.
پس الالحساب یک فولدر بنام src و داخل اون یک فایل بنام index.js درست میکنیم.
حالا برمیگردیم به اون فایل index.php که قرار هست وردپرس برامون بارگذاری کنه.


<html lang="fa" dir="rtl">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WP REACT</title>
</head>

<body>
    <div id="app"></div>
    <script src="<?= WP_REACT_PLUGIN_URI . 'templates/resources/dist/app.bundle.js' ?>"></script>
</body>

</html>

فکر کنم دیگه کم کم باید متوجه شده باشین چه اتفاقی داره میفته.
ما یک فایل php داریم که در یک روت خاص توسط وردپرس بارگذاری میشه؛ در این فایل، یک فایل جاوااسکریپتی قرار داره که لاجیک react ما رو شامل میشه و توسط webpack باندل میشه.
در فولدر src سه فایل بنام های index.js و App.jsx و App.css داریم که بترتیب شامل محتوای زیر اند:

import React from "react";
import { render } from "react-dom";
import App from "./App";
import { BrowserRouter } from "react-router-dom";

const app = document.querySelector("#app");

render( 
    <BrowserRouter>
        <App />
    </BrowserRouter>,
    app
);
import React from "react";
import { Route, Switch, Link } from "react-router-dom";
import Home from "./pages/Home";
import Posts from "./pages/Posts";
import About from "./pages/About";

import "./App.css"

export default function App() {
    return (
        <>
            <ul>
                <li>
                    <Link to="/wp-react">Home Page</Link>
                </li>
                <li>
                    <Link to="/wp-react/posts">Posts Page</Link>
                </li>
                <li>
                    <Link to="/wp-react/about">About Page</Link>
                </li>
            </ul>

            <Switch>
                <Route path="/wp-react/posts">
                    <Posts />
                </Route>
                <Route path="/wp-react/about">
                    <About />
                </Route>
                <Route exact path="/wp-react">
                    <Home />
                </Route>
            </Switch>
        </>
    );
}
ul {
    list-style: none;
    display: flex;
}

ul li {
    padding: 1rem;
    border-bottom: 1px solid lightgrey;
}

همینطور داخل این فولدر، یک فولدر دیگه بنام pages داریم که سه فایل Home.jsx و Posts.jsx و About.jsx رو شامل میشه.

Home.jsx:

import React from "react";
import {Button} from "@material-ui/core";

export default function App() {
    return (
        <div>
            <Button color={"default"}>I'm from Material UI</Button>
            <p>Home Page</p>
        </div>
    );
}

Posts.jsx:

import React from "react";

export default function App() {
    return (
        <div>
            <p>Posts Page</p>
        </div>
    );
}

About.jsx:

import React from "react";

export default function App() {
    return (
        <div>
            <p>About Page</p>
        </div>
    );
}

خب تبریک میگم
اپلیکیشن ما آماده استفاده است. کافیه دو خط زیر رو به بخش scripts فایل package.json اضافه کنید

"build": "webpack",
"watch": "webpack --watch"

و سپس دستور npm run watch رو وارد میکنیم و صبر میکنیم تا همه ی کد های react ما درون فایل app.bundle.js باندل بشه.
پلاگین رو فعال میکنیم و آدرس localhost:5000/wp-react رو باز میکنیم. (نکته آحر مقاله رو حتما بخونید)

تصویر خروجی

ریکت با موفقیت به وردپرس اضافه شده و روتر مثل همیشه سریع کار میکنه و متریال هم آماده است تا ظاهر زیبا به پروژمون بده.

این سیستم مناسب پلاگین های فوق حرفه ای وردپرس مثل صفحه سازها، پنل های کاربری پیشرفته یا یک ایده خفن هست که مسلما سئو در این صفحات هم نباید براتون مهم باشه.

توجه

  • بهتر هست برای اجرای درست برنامه، وردپرس رو از طریق فولدر htdocs داخل xampp یا مشابه اون در wamp اجرا نکنید. کافیه در فولدر اصلی وردپرستون دستور php -S localhost:5000 رو اجرا کنید تا وردپرس در آدرس localhost:5000 براتون در دسترس باشه. البته اگر وردپرس رو در htdocs بالاآوردین و بعد خواستین از طریق سرور دستی php، اون رو اجرا کنید، باید مقدار دو ردیف اول جدول wp-options دیتابیس رو به http://localhost:5000 تغییر بدین.
  • اگر در حین دولوپ ریکت، تغییرات در صفحه مورد نظر ایجاد نشد، صفحه رو با زدن دکمه های کنترل + شیفت و R بارگذاری کنید تا کش مرورگر پاک بشه.
  • شاید براتون این سوال پیش بیاد چرا بجای استفاده از پلاگین، از page template استفاده نکردیم و با ساختن یک برگه و بدون نیاز به نوشتن روت اختصاصی در وردپرس کارمون رو آسون نکردیم؟
    باید بگم اگر این کار رو بکنید باز هم کدتون کار میکنه و روتر هم کار میکنه و مشکلی بجود نمیاد. اما در صورتی که توسط روتر به مثلا صفحه about منتقل بشین و در این صفحه مرورگر رو رفرش کنید، با ارور 404 مواجه میشید چرا که این درخواست دیگه به ریکت منتقل نمیشه و وظیفه هندل کردنش با وردپرسه. ما با نوشتن این روت اختصاصی، کاری کردیم که هر صفحه ای بعد از این آدرس (wp-react/) درخواست بشه، باز هم صفحه index.php توسط وردپرس بارگذاری بشه و این react باشه که وظیفه هندل کردنش رو به عهده بگیره.

امیدوارم این مقاله برای شما مفید واقع شده باشه. خیلی خیلی خوشحال میشم نظراتتون رو برام ارسال کنید.

چه امتیازی برای این مقاله میدهید؟

خیلی بد
بد
متوسط
خوب
عالی
5 از 2 رای

/@hamedniroomand
حامد نیرومند
برنامه‌نویس

frontman

دیدگاه و پرسش

برای ارسال دیدگاه لازم است وارد شده یا ثبت‌نام کنید ورود یا ثبت‌نام

در حال دریافت نظرات از سرور، لطفا منتظر بمانید

در حال دریافت نظرات از سرور، لطفا منتظر بمانید