如何将WordPress$wpdb中的数据放入Reaction Gutenberg BLOCKS前端?

时间:2021-01-30 作者:Marc_L

我使用$wpdb进行mysql查询,并从php文件中获取数据。

$results = $wpdb->get_results("SELECT * FROM table_name"); 
现在,我已经向wordpress api注册了一个Gutenberg块。。

组件是。js文件,在引擎盖下使用(Wordpress React):

import { registerBlockType } from "@wordpress/blocks";
import { __ } from "@wordpress/i18n";
import edit from "./pruefungenEdit";

registerBlockType("mytheme-blocks/pruefungen", {
    title: __("Pruefungen Block", "mytheme-blocks"),
    description: __("Display a Table of exams", "mytheme-blocks"),
    category: "mytheme-category",
    icon: {
        background: "#f03",
        foreground: "#fff",
        src: "dashicons-database",
    },
    keywords: [__("pruefungenBlock", "mytheme-blocks")],
    edit: edit,
    save: () => {
        return <p>Test</p>;
    },
});
这是我用于上述edit()函数的React组件:

import { Component } from "@wordpress/element";
import { withSelect } from "@wordpress/data";
import { __ } from "@wordpress/i18n";

class PruefungenEdit extends Component {

    render() {
        //where to get the data from the query in .php file??
        return <div>Data...</div>;
    }
}

export default PruefungenEdit;
显然,我不能在我的内部使用php代码。js react文件。。我考虑设置一个小型nodejs服务器来查询我的localhost mysql表,并通过自定义api路由发送数据。然后我在react前端查询该路由并显示数据。。。但这对我来说似乎太多了,我的意思是php本身就是某种后端,Wordpress不提供查询mysql数据并以某种方式将其发送到前端的可能性吗?

我现在的问题是,如何将php文件中的数据获取到我为块编辑器前端注册的gutenberg块中?

EDIT - SOLUTION: It was easy to do with registering a custom endpoint and just querying that endpoint inside react frontend...

add_action( \'rest_api_init\', function () {
  register_rest_route( \'wp/v1\', \'/employees\', array(
    \'methods\' => \'GET\',
    \'callback\' => \'get_employees\'
    ));
});

function get_employees() {
    global $wpdb;
    $xmlArr = getparsedXMLArray();
    $uniqueIDArr = getUniqueID($xmlArr);

    $kurs_db = $wpdb->get_results(" SELECT DISTINCT kurs_ort_id, kurs_ort FROM ".$wpdb->prefix . "bsa_location ");
    $objJsonDocument = json_encode($kurs_db);
    $pruefungen = json_decode($objJsonDocument, TRUE);
    $foundPlaces = getAssociatedPlaces($pruefungen, $uniqueIDArr);

    $finishedData = addPlace($xmlArr, $foundPlaces);
    return $finishedData;
}
前端材料:

import { Component } from "@wordpress/element";
import { __ } from "@wordpress/i18n";
import apiFetch from "@wordpress/api-fetch";

class PruefungenEdit extends Component {
    constructor(props) {
        super(props);
        this.state = {
            error: null,
            isLoaded: false,
            employees: [],
        };
    }

    componentDidMount() {
        try {
            apiFetch({
                path: "/wp/v1/employees",
            }).then((employees) => {
                this.setState({ employees, isLoaded: true });
            });
        } catch (error) {
            console.log(error);
            this.setState({
                error: error,
                isLoaded: true,
            });
        }
    }

    render() {
        const { error, isLoaded, employees } = this.state;
        if (error) {
            return <div>Error: {error.message}</div>;
        } else if (!isLoaded) {
            return <div>Loading...</div>;
        } else {
            return (
                <div className={"container"}>
                    <div className="row">
                        <div className="col-xs-12">
                            <table
                                id="pruefungentable"
                                className="table striped dark"
                                style={{ width: "100%" }}
                            >
                                <thead className="thead-dark ">
                                    <tr scope="row" className="table-danger">
                                        <th>#</th>
                                        <th>{__("KursID")}</th>
                                        <th>{__("KursOrt")}</th>
                                        <th>{__("Modul")}</th>
                                        <th>{__("Datum")}</th>
                                    </tr>
                                </thead>
                                <tbody>
                                    {employees.map((employee, index) => (
                                        <tr key={index}>
                                            <td>{index}</td>
                                            <td>{employee.KursID}</td>
                                            <td>{employee.KursOrt}</td>
                                            <td>{employee.Modul}</td>
                                            <td>{employee.Datum}</td>
                                        </tr>
                                    ))}
                                </tbody>
                            </table>
                        </div>
                    </div>
                </div>
            );
        }
    }
}

export default PruefungenEdit;

1 个回复
最合适的回答,由SO网友:Sally CJ 整理而成

实际上,有很多方法可以满足你的要求,但我将给你一个基于this example on the official React website, 它使用AJAX和基于类的组件(但也有一个使用函数组件的示例hooks).

对于PHP部分,我们将创建custom REST API endpoint 出于测试目的,我们将返回一个包含两个项的数组,每个项都有三个属性:id, nameprice.

至于AJAX部分,我们将使用apiFetch() in the @wordpress/api-fetch package 要从自定义端点获取数据,只需使用本机fetch() 函数,但使用apiFetch(), 如果您的端点需要/需要authentication 因为您不需要担心cookie nonce,因为它已经包含在apiFetch().

代码PHP-注册自定义REST API端点:

add_action( \'rest_api_init\', \'my_rest_api_init\', 10, 1 );
function my_rest_api_init() {
    register_rest_route( \'my-plugin/v1\', \'/items\', array(
        \'methods\'             => \'GET\',
        \'permission_callback\' => \'__return_true\', // *always set a permission callback
        \'callback\'            => function ( $request ) {
            return array(
                array( \'id\' => 1, \'name\' => \'Apples\', \'price\' => \'$2\' ),

                // I used is_user_logged_in() so you can see that apiFetch() by default
                // sends the cookie nonce when making an API request.
                array( \'id\' => 2, \'name\' => \'Peaches\', // wrapped
                    \'price\' => is_user_logged_in() ? \'FREE :)\' : \'$5\' ),
            );
        },
    ) );
}
PruefungenEdit 组件:

// don\'t forget to import the apiFetch()
import apiFetch from \'@wordpress/api-fetch\';

class PruefungenEdit extends Component {
    constructor( props ) {
        super( props );
        this.state = {
            error: null,
            isLoaded: false,
            items: [],
        };
    }

    componentDidMount() {
        apiFetch( { path: \'my-plugin/v1/items\' } )
            .then(
                ( items ) => {
                    this.setState( {
                        isLoaded: true,
                        items,
                    } );
                },
                // Note: It\'s important to handle errors here instead of a catch() block
                // so that we don\'t swallow exceptions from actual bugs in components.
                ( error ) => {
                    this.setState( {
                        isLoaded: true,
                        error,
                    } );
                }
        );
    }

    render() {
        const { error, isLoaded, items } = this.state;

        // If there\'s an error in fetching the remote data, display the error.
        if ( error ) {
            return <div>Error: { error.message }</div>;
        // If the data is still being loaded, show a loading message/icon/etc.
        } else if ( ! isLoaded ) {
            return <div>Loading...</div>;
        // Data loaded successfully; so let\'s show it.
        } else {
            return (
                <ul>
                { items.map( item => (
                    <li key={ item.id }>
                        { item.name } <i>{ item.price }</i>
                    </li>
                ) ) }
                </ul>
            );
        }
    }
}